summaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp3
-rw-r--r--test/CodeGenCXX/Inputs/debug-info-class-limited.cpp11
-rw-r--r--test/CodeGenCXX/PR20038.cpp2
-rw-r--r--test/CodeGenCXX/PR26569.cpp20
-rw-r--r--test/CodeGenCXX/PR28220.cpp19
-rw-r--r--test/CodeGenCXX/align-avx-complete-objects.cpp4
-rw-r--r--test/CodeGenCXX/alignment.cpp4
-rw-r--r--test/CodeGenCXX/arm-swiftcall.cpp115
-rw-r--r--test/CodeGenCXX/arm.cpp18
-rw-r--r--test/CodeGenCXX/atomicinit.cpp10
-rw-r--r--test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp108
-rw-r--r--test/CodeGenCXX/attr-x86-interrupt.cpp35
-rw-r--r--test/CodeGenCXX/c-linkage.cpp4
-rw-r--r--test/CodeGenCXX/cfi-blacklist.cpp15
-rw-r--r--test/CodeGenCXX/cfi-cast.cpp79
-rw-r--r--test/CodeGenCXX/cfi-cross-dso.cpp12
-rw-r--r--test/CodeGenCXX/cfi-icall.cpp9
-rw-r--r--test/CodeGenCXX/cfi-ms-rtti.cpp8
-rw-r--r--test/CodeGenCXX/cfi-nvcall.cpp12
-rw-r--r--test/CodeGenCXX/cfi-speculative-vtable.cpp14
-rw-r--r--test/CodeGenCXX/cfi-stats.cpp51
-rw-r--r--test/CodeGenCXX/cfi-vcall.cpp188
-rw-r--r--test/CodeGenCXX/const-init-cxx11.cpp6
-rw-r--r--test/CodeGenCXX/const-init.cpp7
-rw-r--r--test/CodeGenCXX/constructor-init.cpp6
-rw-r--r--test/CodeGenCXX/copy-constructor-elim.cpp2
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis-2.cpp2
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis.cpp2
-rw-r--r--test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp2
-rw-r--r--test/CodeGenCXX/cxx11-exception-spec.cpp17
-rw-r--r--test/CodeGenCXX/cxx11-initializer-array-new.cpp6
-rw-r--r--test/CodeGenCXX/cxx11-thread-local-reference.cpp13
-rw-r--r--test/CodeGenCXX/cxx11-thread-local.cpp16
-rw-r--r--test/CodeGenCXX/cxx1z-constexpr-if.cpp21
-rw-r--r--test/CodeGenCXX/cxx1z-init-statement.cpp70
-rw-r--r--test/CodeGenCXX/cxx1z-initializer-aggregate.cpp114
-rw-r--r--test/CodeGenCXX/cxx1z-inline-variables.cpp83
-rw-r--r--test/CodeGenCXX/cxx1z-lambda-star-this.cpp31
-rw-r--r--test/CodeGenCXX/debug-info-access.cpp5
-rw-r--r--test/CodeGenCXX/debug-info-anon-union-vars.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-artificial-arg.cpp7
-rw-r--r--test/CodeGenCXX/debug-info-calling-conventions.cpp26
-rw-r--r--test/CodeGenCXX/debug-info-class-limited-plugin.test2
-rw-r--r--test/CodeGenCXX/debug-info-class-limited.test2
-rw-r--r--test/CodeGenCXX/debug-info-class.cpp51
-rw-r--r--test/CodeGenCXX/debug-info-codeview-display-name.cpp56
-rw-r--r--test/CodeGenCXX/debug-info-cxx1y.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-enum-class.cpp10
-rw-r--r--test/CodeGenCXX/debug-info-function-context.cpp9
-rw-r--r--test/CodeGenCXX/debug-info-global.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-indirect-field-decl.cpp5
-rw-r--r--test/CodeGenCXX/debug-info-limited.cpp5
-rw-r--r--test/CodeGenCXX/debug-info-line-if.cpp28
-rw-r--r--test/CodeGenCXX/debug-info-line.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-member-call.cpp24
-rw-r--r--test/CodeGenCXX/debug-info-method.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-ms-abi.cpp30
-rw-r--r--test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp20
-rw-r--r--test/CodeGenCXX/debug-info-ms-bitfields.cpp10
-rw-r--r--test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp52
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp54
-rw-r--r--test/CodeGenCXX/debug-info-nodebug.cpp55
-rw-r--r--test/CodeGenCXX/debug-info-ptr-to-member-function.cpp10
-rw-r--r--test/CodeGenCXX/debug-info-scoped-class.cpp15
-rw-r--r--test/CodeGenCXX/debug-info-static-member.cpp68
-rw-r--r--test/CodeGenCXX/debug-info-template-explicit-specialization.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-template-limit.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp59
-rw-r--r--test/CodeGenCXX/debug-info-template-quals.cpp12
-rw-r--r--test/CodeGenCXX/debug-info-template.cpp158
-rw-r--r--test/CodeGenCXX/debug-info-varargs.cpp14
-rw-r--r--test/CodeGenCXX/debug-info.cpp124
-rw-r--r--test/CodeGenCXX/debug-lambda-expressions.cpp63
-rw-r--r--test/CodeGenCXX/debug-lambda-this.cpp5
-rw-r--r--test/CodeGenCXX/default_calling_conv.cpp34
-rw-r--r--test/CodeGenCXX/delete-two-arg.cpp4
-rw-r--r--test/CodeGenCXX/destructors.cpp64
-rw-r--r--test/CodeGenCXX/discard-name-values.cpp10
-rw-r--r--test/CodeGenCXX/dllexport-members.cpp32
-rw-r--r--test/CodeGenCXX/dllexport-ms-friend.cpp22
-rw-r--r--test/CodeGenCXX/dllexport-pr26549.cpp9
-rw-r--r--test/CodeGenCXX/dllexport.cpp128
-rw-r--r--test/CodeGenCXX/dllimport-members.cpp28
-rw-r--r--test/CodeGenCXX/dllimport-rtti.cpp3
-rw-r--r--test/CodeGenCXX/dllimport.cpp76
-rw-r--r--test/CodeGenCXX/duplicate-mangled-name.cpp43
-rw-r--r--test/CodeGenCXX/eh.cpp22
-rw-r--r--test/CodeGenCXX/exceptions-cxx-ehsc.cpp31
-rw-r--r--test/CodeGenCXX/exceptions-cxx-new.cpp6
-rw-r--r--test/CodeGenCXX/exceptions-seh-filter-captures.cpp8
-rw-r--r--test/CodeGenCXX/exceptions-seh.cpp2
-rw-r--r--test/CodeGenCXX/exceptions.cpp14
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp23
-rw-r--r--test/CodeGenCXX/extern-c.cpp19
-rw-r--r--test/CodeGenCXX/float128-declarations.cpp138
-rw-r--r--test/CodeGenCXX/goto.cpp2
-rw-r--r--test/CodeGenCXX/inheriting-constructor.cpp406
-rw-r--r--test/CodeGenCXX/init-invariant.cpp2
-rw-r--r--test/CodeGenCXX/inline-hint.cpp96
-rw-r--r--test/CodeGenCXX/lambda-expressions.cpp10
-rw-r--r--test/CodeGenCXX/linetable-virtual-variadic.cpp4
-rw-r--r--test/CodeGenCXX/lto-visibility-inference.cpp107
-rw-r--r--test/CodeGenCXX/mangle-abi-tag.cpp205
-rw-r--r--test/CodeGenCXX/mangle-address-space.cpp3
-rw-r--r--test/CodeGenCXX/mangle-ms-cxx11.cpp44
-rw-r--r--test/CodeGenCXX/mangle-ms-cxx14.cpp15
-rw-r--r--test/CodeGenCXX/mangle-ms-md5.cpp11
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp5
-rw-r--r--test/CodeGenCXX/mangle-template.cpp11
-rw-r--r--test/CodeGenCXX/mangle.cpp10
-rw-r--r--test/CodeGenCXX/microsoft-abi-array-cookies.cpp6
-rw-r--r--test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-catch.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp130
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-terminate.cpp7
-rw-r--r--test/CodeGenCXX/microsoft-abi-extern-template.cpp25
-rwxr-xr-xtest/CodeGenCXX/microsoft-abi-member-pointers.cpp21
-rw-r--r--test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp53
-rw-r--r--test/CodeGenCXX/microsoft-abi-structors.cpp17
-rw-r--r--test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp23
-rw-r--r--test/CodeGenCXX/microsoft-abi-throw.cpp19
-rw-r--r--test/CodeGenCXX/microsoft-abi-try-throw.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-typeid.cpp21
-rw-r--r--test/CodeGenCXX/microsoft-abi-vbtables.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-vftables.cpp13
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp40
-rw-r--r--test/CodeGenCXX/microsoft-interface.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-templ-uuidof.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-uuidof.cpp2
-rw-r--r--test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp12
-rw-r--r--test/CodeGenCXX/multi-dim-operator-new.cpp6
-rw-r--r--test/CodeGenCXX/new-alias.cpp2
-rw-r--r--test/CodeGenCXX/new-array-init.cpp4
-rw-r--r--test/CodeGenCXX/new-overflow.cpp18
-rw-r--r--test/CodeGenCXX/new.cpp35
-rw-r--r--test/CodeGenCXX/operator-new.cpp6
-rw-r--r--test/CodeGenCXX/optnone-and-attributes.cpp2
-rw-r--r--test/CodeGenCXX/optnone-class-members.cpp4
-rw-r--r--test/CodeGenCXX/optnone-def-decl.cpp4
-rw-r--r--test/CodeGenCXX/optnone-templates.cpp2
-rw-r--r--test/CodeGenCXX/pass-object-size.cpp37
-rw-r--r--test/CodeGenCXX/pr20719.cpp4
-rw-r--r--test/CodeGenCXX/pr27030.cpp16
-rw-r--r--test/CodeGenCXX/pr28360.cpp16
-rw-r--r--test/CodeGenCXX/pragma-loop.cpp13
-rw-r--r--test/CodeGenCXX/rtti-fundamental.cpp10
-rw-r--r--test/CodeGenCXX/sections.cpp29
-rw-r--r--test/CodeGenCXX/skip-vtable-pointer-initialization.cpp14
-rw-r--r--test/CodeGenCXX/stack-reuse.cpp4
-rw-r--r--test/CodeGenCXX/static-destructor.cpp33
-rw-r--r--test/CodeGenCXX/static-init.cpp2
-rw-r--r--test/CodeGenCXX/strict-vtable-pointers.cpp4
-rw-r--r--test/CodeGenCXX/type-metadata.cpp248
-rw-r--r--test/CodeGenCXX/virtual-base-ctor.cpp2
-rw-r--r--test/CodeGenCXX/virtual-function-attrs.cpp14
-rw-r--r--test/CodeGenCXX/vla-consruct.cpp139
-rw-r--r--test/CodeGenCXX/vtable-assume-load.cpp14
-rw-r--r--test/CodeGenCXX/vtable-key-function-arm.cpp6
-rw-r--r--test/CodeGenCXX/vtable-key-function-ios.cpp6
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp2
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp8
-rw-r--r--test/CodeGenCXX/vtt-layout.cpp10
163 files changed, 3988 insertions, 938 deletions
diff --git a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
index 3828388d48ea..dd5fa3e08fc2 100644
--- a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
+++ b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
@@ -12,10 +12,11 @@ int f(void) {
// CHECK: declare i32 @_Z1cv() [[NUW_RN:#[0-9]+]]
// CHECK: declare i32 @_Z1pv() [[NUW_RO:#[0-9]+]]
-// CHECK: declare i32 @_Z1tv() [[TF]]
+// CHECK: declare i32 @_Z1tv() [[TF2:#[0-9]+]]
// CHECK: attributes [[TF]] = { {{.*}} }
// CHECK: attributes [[NUW_RN]] = { nounwind readnone{{.*}} }
// CHECK: attributes [[NUW_RO]] = { nounwind readonly{{.*}} }
+// CHECK: attributes [[TF2]] = { {{.*}} }
// CHECK: attributes [[NUW_RN_CALL]] = { nounwind readnone }
// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly }
diff --git a/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp b/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
index 17fa456a45d9..34a1cfa00e2c 100644
--- a/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
+++ b/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
@@ -1,5 +1,6 @@
-// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "PR16214",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PR16214",{{.*}} line: [[@LINE+2]],{{.*}}
+// CHECK-NOT: DIFlagFwdDecl
struct PR16214 {
int i;
};
@@ -10,7 +11,8 @@ bar *a;
bar b;
namespace PR14467 {
-// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+2]],{{.*}}
+// CHECK-NOT: DIFlagFwdDecl
struct foo {
};
@@ -21,7 +23,7 @@ foo *bar(foo *a) {
}
namespace test1 {
-// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagFwdDecl
struct foo {
};
@@ -35,7 +37,8 @@ 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: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+2]],{{.*}}
+// CHECK-NOT: DIFlagFwdDecl
struct foo {
};
diff --git a/test/CodeGenCXX/PR20038.cpp b/test/CodeGenCXX/PR20038.cpp
index 2d7043dcda33..095705f389bf 100644
--- a/test/CodeGenCXX/PR20038.cpp
+++ b/test/CodeGenCXX/PR20038.cpp
@@ -7,8 +7,8 @@ extern bool b;
// CHECK: call {{.*}}, !dbg [[DTOR_CALL1_LOC:![0-9]*]]
// CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]]
// CHECK: [[FUN1:.*]] = distinct !DISubprogram(name: "fun1",{{.*}} isDefinition: true
-// CHECK: [[FUN2:.*]] = distinct !DISubprogram(name: "fun2",{{.*}} isDefinition: true
// CHECK: [[DTOR_CALL1_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN1]])
void fun1() { b && (C(), 1); }
+// CHECK: [[FUN2:.*]] = distinct !DISubprogram(name: "fun2",{{.*}} isDefinition: true
// CHECK: [[DTOR_CALL2_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN2]])
bool fun2() { return (C(), b) && 0; }
diff --git a/test/CodeGenCXX/PR26569.cpp b/test/CodeGenCXX/PR26569.cpp
new file mode 100644
index 000000000000..3e2d2ffeba14
--- /dev/null
+++ b/test/CodeGenCXX/PR26569.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-optzns %s -o - | FileCheck %s
+
+class A {
+ virtual void m_fn1();
+};
+template <typename>
+class B : virtual A {};
+
+extern template class __declspec(dllimport) B<int>;
+class __declspec(dllexport) C : B<int> {};
+
+// CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)]
+// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B@H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)], comdat($"\01??_S?$B@H@@6B@")
+// CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1@A@@EAEXXZ" to i8*)], comdat($"\01??_7A@@6B@")
+
+// CHECK-DAG: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_C]], i32 0, i32 1)
+// CHECK-DAG: @"\01??_S?$B@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_B]], i32 0, i32 1)
+// CHECK-DAG: @"\01??_7A@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_A]], i32 0, i32 1)
+
+// CHECK-DAG: @"\01??_8?$B@H@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
diff --git a/test/CodeGenCXX/PR28220.cpp b/test/CodeGenCXX/PR28220.cpp
new file mode 100644
index 000000000000..6262c87de206
--- /dev/null
+++ b/test/CodeGenCXX/PR28220.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+
+template <typename>
+struct __declspec(dllimport) S {
+ S();
+};
+
+template <typename T>
+struct __declspec(dllimport) U {
+ static S<T> u;
+};
+
+template <typename T>
+S<T> U<T>::u;
+
+template S<int> U<int>::u;
+// CHECK-NOT: define internal void @"\01??__Eu@?$U@H@@2U?$S@H@@A@YAXXZ"(
+
+S<int> &i = U<int>::u;
diff --git a/test/CodeGenCXX/align-avx-complete-objects.cpp b/test/CodeGenCXX/align-avx-complete-objects.cpp
index 6ab17f5d656b..ad4a91428d25 100644
--- a/test/CodeGenCXX/align-avx-complete-objects.cpp
+++ b/test/CodeGenCXX/align-avx-complete-objects.cpp
@@ -13,7 +13,7 @@ volatile float TestAlign(void)
}
// CHECK: [[R:%.*]] = alloca <8 x float>, align 32
-// CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @_Znwm(i64 32)
+// CHECK-NEXT: [[CALL:%.*]] = call 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>*, <8 x float>** [[P]], align 8
@@ -42,7 +42,7 @@ volatile float TestAlign2(void)
}
// CHECK: [[R:%.*]] = alloca <8 x float>, align 32
-// CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @_Znwm(i64 32)
+// CHECK-NEXT: [[CALL:%.*]] = call 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>*, <8 x float>** [[P]], align 8
diff --git a/test/CodeGenCXX/alignment.cpp b/test/CodeGenCXX/alignment.cpp
index 2a1fe71f961b..4c44badd21cd 100644
--- a/test/CodeGenCXX/alignment.cpp
+++ b/test/CodeGenCXX/alignment.cpp
@@ -32,7 +32,7 @@ namespace test0 {
// CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
// CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 4
b.onebit = int_source();
-
+
// CHECK: [[B_P:%.*]] = load [[B]]*, [[B]]**
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
// CHECK: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
@@ -60,7 +60,7 @@ namespace test0 {
// CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
// CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 2
c.onebit = int_source();
-
+
// CHECK: [[C_P:%.*]] = load [[C]]*, [[C]]**
// CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
// CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
diff --git a/test/CodeGenCXX/arm-swiftcall.cpp b/test/CodeGenCXX/arm-swiftcall.cpp
new file mode 100644
index 000000000000..535350c808d3
--- /dev/null
+++ b/test/CodeGenCXX/arm-swiftcall.cpp
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage | FileCheck %s
+
+// This isn't really testing anything ARM-specific; it's just a convenient
+// 32-bit platform.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define OUT __attribute__((swift_indirect_result))
+#define ERROR __attribute__((swift_error_result))
+#define CONTEXT __attribute__((swift_context))
+
+/*****************************************************************************/
+/********************************** LOWERING *********************************/
+/*****************************************************************************/
+
+#define TEST(TYPE) \
+ extern "C" SWIFTCALL TYPE return_##TYPE(void) { \
+ TYPE result = {}; \
+ return result; \
+ } \
+ extern "C" SWIFTCALL void take_##TYPE(TYPE v) { \
+ } \
+ extern "C" void test_##TYPE() { \
+ take_##TYPE(return_##TYPE()); \
+ }
+
+/*****************************************************************************/
+/*********************************** STRUCTS *********************************/
+/*****************************************************************************/
+
+typedef struct {
+} struct_empty;
+TEST(struct_empty);
+// CHECK-LABEL: define {{.*}} @return_struct_empty()
+// CHECK: ret void
+// CHECK-LABEL: define {{.*}} @take_struct_empty()
+// CHECK: ret void
+
+// This is only properly testable in C++ because it relies on empty structs
+// actually taking up space in a structure without requiring any extra data
+// to be passed.
+typedef struct {
+ int x;
+ struct_empty padding[2];
+ char c1;
+ float f0;
+ float f1;
+} struct_1;
+TEST(struct_1);
+// CHECK-LABEL: define {{.*}} @return_struct_1()
+// CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4
+// CHECK: @llvm.memset
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, \[2 x i8\], i8, \[1 x i8\], float, float }]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: [[SECOND:%.*]] = load i8, i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i8, float, float }]] undef, i32 [[FIRST]], 0
+// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i8 [[SECOND]], 1
+// CHECK: [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2
+// CHECK: [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3
+// CHECK: ret [[UAGG]] [[T3]]
+// CHECK-LABEL: define {{.*}} @take_struct_1(i32, i8, float, float)
+// CHECK: [[V:%.*]] = alloca [[REC]], align 4
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: store i32 %0, i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: store i8 %1, i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: store float %2, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: store float %3, float* [[T0]], align 4
+// CHECK: ret void
+// CHECK-LABEL: define void @test_struct_1()
+// CHECK: [[TMP:%.*]] = alloca [[REC]], align 4
+// CHECK: [[CALL:%.*]] = call [[SWIFTCC:swiftcc]] [[UAGG]] @return_struct_1()
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
+// CHECK: store i32 [[T1]], i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
+// CHECK: store i8 [[T1]], i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: [[SECOND:%.*]] = load i8, i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align 4
+// CHECK: call [[SWIFTCC]] void @take_struct_1(i32 [[FIRST]], i8 [[SECOND]], float [[THIRD]], float [[FOURTH]])
+// CHECK: ret void
+
+struct struct_indirect_1 {
+ int x;
+ ~struct_indirect_1();
+};
+TEST(struct_indirect_1)
+
+// CHECK-LABEL: define {{.*}} void @return_struct_indirect_1({{.*}} noalias sret
+
+// Should not be byval.
+// CHECK-LABEL: define {{.*}} void @take_struct_indirect_1({{.*}}*{{( %.*)?}})
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 11ae6b24c26e..d0b896d182da 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -109,7 +109,7 @@ namespace test3 {
void a() {
// CHECK-LABEL: define void @_ZN5test31aEv()
- // CHECK: call noalias i8* @_Znam(i32 48)
+ // CHECK: call i8* @_Znam(i32 48)
// CHECK: store i32 4
// CHECK: store i32 10
A *x = new A[10];
@@ -122,7 +122,7 @@ namespace test3 {
// CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
// CHECK: [[OR:%.*]] = or i1
// CHECK: [[SZ:%.*]] = select i1 [[OR]]
- // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
// CHECK: store i32 4
// CHECK: store i32 [[N]]
A *x = new A[n];
@@ -130,7 +130,7 @@ namespace test3 {
void c() {
// CHECK-LABEL: define void @_ZN5test31cEv()
- // CHECK: call noalias i8* @_Znam(i32 808)
+ // CHECK: call i8* @_Znam(i32 808)
// CHECK: store i32 4
// CHECK: store i32 200
A (*x)[20] = new A[10][20];
@@ -143,7 +143,7 @@ namespace test3 {
// CHECK: [[NE:%.*]] = mul i32 [[N]], 20
// CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
// CHECK: [[SZ:%.*]] = select
- // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
// CHECK: store i32 4
// CHECK: store i32 [[NE]]
A (*x)[20] = new A[n][20];
@@ -182,7 +182,7 @@ namespace test4 {
void a() {
// CHECK-LABEL: define void @_ZN5test41aEv()
- // CHECK: call noalias i8* @_Znam(i32 48)
+ // CHECK: call i8* @_Znam(i32 48)
// CHECK: store i32 4
// CHECK: store i32 10
A *x = new A[10];
@@ -194,7 +194,7 @@ namespace test4 {
// CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
// CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
// CHECK: [[SZ:%.*]] = select
- // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
// CHECK: store i32 4
// CHECK: store i32 [[N]]
A *x = new A[n];
@@ -202,7 +202,7 @@ namespace test4 {
void c() {
// CHECK-LABEL: define void @_ZN5test41cEv()
- // CHECK: call noalias i8* @_Znam(i32 808)
+ // CHECK: call i8* @_Znam(i32 808)
// CHECK: store i32 4
// CHECK: store i32 200
A (*x)[20] = new A[10][20];
@@ -215,7 +215,7 @@ namespace test4 {
// CHECK: [[NE:%.*]] = mul i32 [[N]], 20
// CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
// CHECK: [[SZ:%.*]] = select
- // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
// CHECK: store i32 4
// CHECK: store i32 [[NE]]
A (*x)[20] = new A[n][20];
@@ -383,7 +383,7 @@ namespace test9 {
// CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[O0]], [[O1]]
// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
// CHECK-NEXT: [[T4:%.*]] = select i1 [[OVERFLOW]], i32 -1, i32 [[T3]]
-// CHECK-NEXT: [[ALLOC:%.*]] = call noalias i8* @_Znam(i32 [[T4]])
+// CHECK-NEXT: [[ALLOC:%.*]] = call 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, i32* [[T0]], i32 1
diff --git a/test/CodeGenCXX/atomicinit.cpp b/test/CodeGenCXX/atomicinit.cpp
index 5e5174bd06e4..96f44d52f286 100644
--- a/test/CodeGenCXX/atomicinit.cpp
+++ b/test/CodeGenCXX/atomicinit.cpp
@@ -1,13 +1,13 @@
// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 -std=c++11 | FileCheck %s
-// CHECK-DAG: @PR22043 = global i32 0, align 4
+// CHECK-DAG: @PR22043 = local_unnamed_addr global i32 0, align 4
typedef _Atomic(int) AtomicInt;
AtomicInt PR22043 = AtomicInt();
-// CHECK-DAG: @_ZN7PR180978constant1aE = global { i16, i8 } { i16 1, i8 6 }, align 4
-// CHECK-DAG: @_ZN7PR180978constant1bE = global { i16, i8 } { i16 2, i8 6 }, align 4
-// CHECK-DAG: @_ZN7PR180978constant1cE = global { i16, i8 } { i16 3, i8 6 }, align 4
-// CHECK-DAG: @_ZN7PR180978constant1yE = global { { i16, i8 }, i32 } { { i16, i8 } { i16 4, i8 6 }, i32 5 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1aE = local_unnamed_addr global { i16, i8 } { i16 1, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1bE = local_unnamed_addr global { i16, i8 } { i16 2, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1cE = local_unnamed_addr global { i16, i8 } { i16 3, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1yE = local_unnamed_addr global { { i16, i8 }, i32 } { { i16, i8 } { i16 4, i8 6 }, i32 5 }, align 4
struct A {
_Atomic(int) i;
diff --git a/test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp b/test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp
new file mode 100644
index 000000000000..6373cf0b2e0a
--- /dev/null
+++ b/test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+
+template <class T>
+void CheckIntScalarTypes() {
+ // T will be substituted with 'int' and 'enum' types.
+
+ typedef T __attribute__((mode(QI))) T1;
+ typedef T __attribute__((mode(HI))) T2;
+ typedef T __attribute__((mode(SI))) T3;
+ typedef T __attribute__((mode(DI))) T4;
+
+ T1 a1;
+ T2 a2;
+ T3 a3;
+ T4 a4;
+}
+
+template <class T>
+void CheckIntVectorTypes() {
+ // T will be substituted with 'int'.
+
+ typedef int __attribute__((mode(QI))) __attribute__((vector_size(8))) VT_11;
+ typedef T __attribute__((mode(V8QI))) VT_12;
+ typedef int __attribute__((mode(SI))) __attribute__((vector_size(16))) VT_21;
+ typedef T __attribute__((mode(V4SI))) VT_22;
+ typedef int __attribute__((mode(DI))) __attribute__((vector_size(64))) VT_31;
+ typedef T __attribute__((mode(V8DI))) VT_32;
+
+ VT_11 v11;
+ VT_12 v12;
+
+ VT_21 v21;
+ VT_22 v22;
+
+ VT_31 v31;
+ VT_32 v32;
+}
+
+template <class T>
+void CheckFloatVectorTypes() {
+ // T will be substituted with 'float'.
+
+ typedef float __attribute__((mode(SF))) __attribute__((vector_size(128))) VT_41;
+ typedef T __attribute__((mode(V32SF))) VT_42;
+ typedef float __attribute__((mode(DF))) __attribute__((vector_size(256))) VT_51;
+ typedef T __attribute__((mode(V32DF))) VT_52;
+
+ VT_41 v41;
+ VT_42 v42;
+
+ VT_51 v51;
+ VT_52 v52;
+}
+
+template <class T>
+void CheckInstantiationWithModedType() {
+ T x1;
+}
+
+typedef enum { A1, B1 } EnumTy;
+typedef int __attribute__((mode(DI))) Int64Ty1;
+typedef enum __attribute__((mode(DI))) { A2 } Int64Ty2;
+typedef int __attribute__((mode(V8HI))) IntVecTy1;
+
+void test() {
+
+ // CHECK: define {{.*}} void @_Z19CheckIntScalarTypesIiEvv()
+ // CHECK: %{{.+}} = alloca i8
+ // CHECK: %{{.+}} = alloca i16
+ // CHECK: %{{.+}} = alloca i32
+ // CHECK: %{{.+}} = alloca i64
+ CheckIntScalarTypes<int>();
+
+ // CHECK: define {{.*}} void @_Z19CheckIntScalarTypesI6EnumTyEvv()
+ // CHECK: %{{.+}} = alloca i8
+ // CHECK: %{{.+}} = alloca i16
+ // CHECK: %{{.+}} = alloca i32
+ // CHECK: %{{.+}} = alloca i64
+ CheckIntScalarTypes<EnumTy>();
+
+ // CHECK: define {{.*}} void @_Z19CheckIntVectorTypesIiEvv()
+ // CHECK: %{{.+}} = alloca <8 x i8>
+ // CHECK: %{{.+}} = alloca <8 x i8>
+ // CHECK: %{{.+}} = alloca <4 x i32>
+ // CHECK: %{{.+}} = alloca <4 x i32>
+ // CHECK: %{{.+}} = alloca <8 x i64>
+ // CHECK: %{{.+}} = alloca <8 x i64>
+ CheckIntVectorTypes<int>();
+
+ // CHECK: define {{.*}} void @_Z21CheckFloatVectorTypesIfEvv()
+ // CHECK: %{{.+}} = alloca <32 x float>
+ // CHECK: %{{.+}} = alloca <32 x float>
+ // CHECK: %{{.+}} = alloca <32 x double>
+ // CHECK: %{{.+}} = alloca <32 x double>
+ CheckFloatVectorTypes<float>();
+
+ // CHECK: define {{.*}} void @_Z31CheckInstantiationWithModedTypeIlEvv()
+ // CHECK: [[X1:%.+]] = alloca i64
+ CheckInstantiationWithModedType<Int64Ty1>();
+
+ // CHECK: define {{.*}} void @_Z31CheckInstantiationWithModedTypeI8Int64Ty2Evv()
+ // CHECK: [[X1]] = alloca i64
+ CheckInstantiationWithModedType<Int64Ty2>();
+
+ // CHECK: define {{.*}} void @_Z31CheckInstantiationWithModedTypeIDv8_sEvv()
+ // CHECK: [[X1]] = alloca <8 x i16>
+ CheckInstantiationWithModedType<IntVecTy1>();
+}
diff --git a/test/CodeGenCXX/attr-x86-interrupt.cpp b/test/CodeGenCXX/attr-x86-interrupt.cpp
new file mode 100644
index 000000000000..500010469035
--- /dev/null
+++ b/test/CodeGenCXX/attr-x86-interrupt.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64_LINUX
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_LINUX
+// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64_WIN
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_WIN
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64_LINUX
+
+#ifdef __x86_64__
+typedef __UINT64_TYPE__ uword;
+#else
+typedef __UINT32_TYPE__ uword;
+#endif
+
+__attribute__((interrupt)) void foo7(int *a, uword b) {}
+namespace S {
+__attribute__((interrupt)) void foo8(int *a) {}
+}
+struct St {
+static void foo9(int *a) __attribute__((interrupt)) {}
+};
+// X86_64_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_64_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i64 %{{.+}})
+// X86_64_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_64_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i32 %{{.+}})
+// X86_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_64_WIN: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_64_WIN: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i64 %{{.+}})
+// X86_64_WIN: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_64_WIN: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_WIN: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_WIN: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i32 %{{.+}})
+// X86_WIN: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_WIN: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
diff --git a/test/CodeGenCXX/c-linkage.cpp b/test/CodeGenCXX/c-linkage.cpp
index a70a22ef08c7..0f4c3277253f 100644
--- a/test/CodeGenCXX/c-linkage.cpp
+++ b/test/CodeGenCXX/c-linkage.cpp
@@ -15,10 +15,10 @@ extern "C" {
extern "C" {
static void test2_f() {
}
- // CHECK-LABEL: define internal {{.*}}void @_Z7test2_fv
+ // CHECK-LABEL: define internal {{.*}}void @_ZL7test2_fv
static void test2_f(int x) {
}
- // CHECK-LABEL: define internal {{.*}}void @_Z7test2_fi
+ // CHECK-LABEL: define internal {{.*}}void @_ZL7test2_fi
void test2_use() {
test2_f();
test2_f(42);
diff --git a/test/CodeGenCXX/cfi-blacklist.cpp b/test/CodeGenCXX/cfi-blacklist.cpp
index 32ed05bcc520..af8a10601d29 100644
--- a/test/CodeGenCXX/cfi-blacklist.cpp
+++ b/test/CodeGenCXX/cfi-blacklist.cpp
@@ -1,9 +1,8 @@
-// RUN: echo "type:attr:uuid" > %t.txt
-// RUN: %clang_cc1 -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOUUID %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
// RUN: echo "type:std::*" > %t.txt
-// RUN: %clang_cc1 -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
-struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) S1 {
+struct S1 {
virtual void f();
};
@@ -16,15 +15,15 @@ struct S2 {
}
// CHECK: define{{.*}}s1f
-// NOSTD: llvm.bitset.test
-// NOUUID-NOT: llvm.bitset.test
+// NOBL: llvm.type.test
+// NOSTD: llvm.type.test
void s1f(S1 *s1) {
s1->f();
}
// CHECK: define{{.*}}s2f
-// NOSTD-NOT: llvm.bitset.test
-// NOUUID: llvm.bitset.test
+// NOBL: llvm.type.test
+// NOSTD-NOT: llvm.type.test
void s2f(std::S2 *s2) {
s2->f();
}
diff --git a/test/CodeGenCXX/cfi-cast.cpp b/test/CodeGenCXX/cfi-cast.cpp
index 0b96cb6506c0..54641b52332b 100644
--- a/test/CodeGenCXX/cfi-cast.cpp
+++ b/test/CodeGenCXX/cfi-cast.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -fsanitize-trap=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 -fsanitize-trap=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 -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-unrelated-cast,cfi-cast-strict -fsanitize-trap=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
@@ -8,6 +8,7 @@
struct A {
virtual void f();
+ int i() const;
};
struct B : A {
@@ -16,9 +17,9 @@ struct B : A {
struct C : A {};
-// CHECK-DCAST-LABEL: define void @_Z3abpP1A
+// CHECK-DCAST-LABEL: define hidden void @_Z3abpP1A
void abp(A *a) {
- // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
// CHECK-DCAST: [[TRAPBB]]
@@ -27,12 +28,12 @@ void abp(A *a) {
// CHECK-DCAST: [[CONTBB]]
// CHECK-DCAST: ret
- static_cast<B*>(a);
+ (void)static_cast<B*>(a);
}
-// CHECK-DCAST-LABEL: define void @_Z3abrR1A
+// CHECK-DCAST-LABEL: define hidden void @_Z3abrR1A
void abr(A &a) {
- // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
// CHECK-DCAST: [[TRAPBB]]
@@ -41,12 +42,12 @@ void abr(A &a) {
// CHECK-DCAST: [[CONTBB]]
// CHECK-DCAST: ret
- static_cast<B&>(a);
+ (void)static_cast<B&>(a);
}
-// CHECK-DCAST-LABEL: define void @_Z4abrrO1A
+// CHECK-DCAST-LABEL: define hidden void @_Z4abrrO1A
void abrr(A &&a) {
- // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
// CHECK-DCAST: [[TRAPBB]]
@@ -55,12 +56,12 @@ void abrr(A &&a) {
// CHECK-DCAST: [[CONTBB]]
// CHECK-DCAST: ret
- static_cast<B&&>(a);
+ (void)static_cast<B&&>(a);
}
-// CHECK-UCAST-LABEL: define void @_Z3vbpPv
+// CHECK-UCAST-LABEL: define hidden void @_Z3vbpPv
void vbp(void *p) {
- // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
// CHECK-UCAST: [[TRAPBB]]
@@ -69,12 +70,12 @@ void vbp(void *p) {
// CHECK-UCAST: [[CONTBB]]
// CHECK-UCAST: ret
- static_cast<B*>(p);
+ (void)static_cast<B*>(p);
}
-// CHECK-UCAST-LABEL: define void @_Z3vbrRc
+// CHECK-UCAST-LABEL: define hidden void @_Z3vbrRc
void vbr(char &r) {
- // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
// CHECK-UCAST: [[TRAPBB]]
@@ -83,12 +84,12 @@ void vbr(char &r) {
// CHECK-UCAST: [[CONTBB]]
// CHECK-UCAST: ret
- reinterpret_cast<B&>(r);
+ (void)reinterpret_cast<B&>(r);
}
-// CHECK-UCAST-LABEL: define void @_Z4vbrrOc
+// CHECK-UCAST-LABEL: define hidden void @_Z4vbrrOc
void vbrr(char &&r) {
- // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
// CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
// CHECK-UCAST: [[TRAPBB]]
@@ -97,29 +98,37 @@ void vbrr(char &&r) {
// CHECK-UCAST: [[CONTBB]]
// CHECK-UCAST: ret
- reinterpret_cast<B&&>(r);
+ (void)reinterpret_cast<B&&>(r);
}
-// CHECK-UCAST-LABEL: define void @_Z3vcpPv
-// CHECK-UCAST-STRICT-LABEL: define void @_Z3vcpPv
+// CHECK-UCAST-LABEL: define hidden void @_Z3vcpPv
+// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3vcpPv
void vcp(void *p) {
- // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
- // CHECK-UCAST-STRICT: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
- static_cast<C*>(p);
+ // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ (void)static_cast<C*>(p);
}
-// CHECK-UCAST-LABEL: define void @_Z3bcpP1B
-// CHECK-UCAST-STRICT-LABEL: define void @_Z3bcpP1B
+// CHECK-UCAST-LABEL: define hidden void @_Z3bcpP1B
+// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3bcpP1B
void bcp(B *p) {
- // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
- // CHECK-UCAST-STRICT: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
- (C *)p;
+ // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ (void)(C *)p;
}
-// CHECK-UCAST-LABEL: define void @_Z8bcp_callP1B
-// CHECK-UCAST-STRICT-LABEL: define void @_Z8bcp_callP1B
+// CHECK-UCAST-LABEL: define hidden void @_Z8bcp_callP1B
+// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z8bcp_callP1B
void bcp_call(B *p) {
- // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
- // CHECK-UCAST-STRICT: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
((C *)p)->f();
}
+
+// CHECK-UCAST-LABEL: define hidden i32 @_Z6a_callP1A
+// CHECK-UCAST-STRICT-LABEL: define hidden i32 @_Z6a_callP1A
+int a_call(A *a) {
+ // CHECK-UCAST-NOT: @llvm.type.test
+ // CHECK-UCAST-STRICT-NOT: @llvm.type.test
+ return a->i();
+}
diff --git a/test/CodeGenCXX/cfi-cross-dso.cpp b/test/CodeGenCXX/cfi-cross-dso.cpp
index fbe6fc83a5c3..d67927d4d2ed 100644
--- a/test/CodeGenCXX/cfi-cross-dso.cpp
+++ b/test/CodeGenCXX/cfi-cross-dso.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM %s
-// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
struct A {
A();
@@ -30,12 +30,12 @@ void g() {
// CHECK: %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)***
// CHECK: %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize
-// ITANIUM: %[[TEST:.*]] = call i1 @llvm.bitset.test(i8* %[[VT2]], metadata !"_ZTS1A"), !nosanitize
-// MS: %[[TEST:.*]] = call i1 @llvm.bitset.test(i8* %[[VT2]], metadata !"?AUA@@"), !nosanitize
+// ITANIUM: %[[TEST:.*]] = call i1 @llvm.type.test(i8* %[[VT2]], metadata !"_ZTS1A"), !nosanitize
+// MS: %[[TEST:.*]] = call i1 @llvm.type.test(i8* %[[VT2]], metadata !"?AUA@@"), !nosanitize
// CHECK: br i1 %[[TEST]], label %[[CONT:.*]], label %[[SLOW:.*]], {{.*}} !nosanitize
// CHECK: [[SLOW]]
-// ITANIUM: call void @__cfi_slowpath(i64 7004155349499253778, i8* %[[VT2]]) {{.*}} !nosanitize
-// MS: call void @__cfi_slowpath(i64 -8005289897957287421, i8* %[[VT2]]) {{.*}} !nosanitize
+// ITANIUM: call void @__cfi_slowpath_diag(i64 7004155349499253778, i8* %[[VT2]], {{.*}}) {{.*}} !nosanitize
+// MS: call void @__cfi_slowpath_diag(i64 -8005289897957287421, i8* %[[VT2]], {{.*}}) {{.*}} !nosanitize
// CHECK: br label %[[CONT]], !nosanitize
// CHECK: [[CONT]]
// CHECK: call void %{{.*}}(%struct.A* %{{.*}})
diff --git a/test/CodeGenCXX/cfi-icall.cpp b/test/CodeGenCXX/cfi-icall.cpp
index eceb92a4421c..c3c6ed309cc6 100644
--- a/test/CodeGenCXX/cfi-icall.cpp
+++ b/test/CodeGenCXX/cfi-icall.cpp
@@ -15,9 +15,12 @@ void f(S *s) {
void g() {
void (*fp)(S *) = f;
- // CHECK: call i1 @llvm.bitset.test(i8* {{.*}}, metadata ![[VOIDS:[0-9]+]])
+ // CHECK: call i1 @llvm.type.test(i8* {{.*}}, metadata [[VOIDS:![0-9]+]])
fp(0);
}
-// ITANIUM: !{![[VOIDS]], void (%"struct.(anonymous namespace)::S"*)* @_ZN12_GLOBAL__N_11fEPNS_1SE, i64 0}
-// MS: !{![[VOIDS]], void (%"struct.(anonymous namespace)::S"*)* @"\01?f@?A@@YAXPEAUS@?A@@@Z", i64 0}
+// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fEPNS_1SE({{.*}} !type [[TS:![0-9]+]]
+// MS: define internal void @"\01?f@?A@@YAXPEAUS@?A@@@Z"({{.*}} !type [[TS:![0-9]+]]
+
+// CHECK: [[VOIDS]] = distinct !{}
+// CHECK: [[TS]] = !{i64 0, [[VOIDS]]}
diff --git a/test/CodeGenCXX/cfi-ms-rtti.cpp b/test/CodeGenCXX/cfi-ms-rtti.cpp
index b6e9175c865c..fbebad4b1b8d 100644
--- a/test/CodeGenCXX/cfi-ms-rtti.cpp
+++ b/test/CodeGenCXX/cfi-ms-rtti.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
-// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
+// RUN: %clang_cc1 -flto -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
+// RUN: %clang_cc1 -flto -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
struct A {
A();
@@ -8,5 +8,5 @@ struct A {
A::A() {}
-// RTTI: !{!"?AUA@@", [2 x i8*]* {{.*}}, i64 8}
-// NO-RTTI: !{!"?AUA@@", [1 x i8*]* {{.*}}, i64 0}
+// RTTI: !{i64 8, !"?AUA@@"}
+// NO-RTTI: !{i64 0, !"?AUA@@"}
diff --git a/test/CodeGenCXX/cfi-nvcall.cpp b/test/CodeGenCXX/cfi-nvcall.cpp
index be4d8448a2e0..e968f05600c2 100644
--- a/test/CodeGenCXX/cfi-nvcall.cpp
+++ b/test/CodeGenCXX/cfi-nvcall.cpp
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-nvcall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-STRICT %s
struct A {
virtual void f();
@@ -17,8 +17,8 @@ struct C : A {
// CHECK-LABEL: @bg
// CHECK-STRICT-LABEL: @bg
extern "C" void bg(B *b) {
- // CHECK: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
- // CHECK-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
b->g();
}
@@ -29,7 +29,7 @@ extern "C" void cg(C *c) {
// 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 !"_ZTS1A")
- // CHECK-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ // CHECK: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
c->g();
}
diff --git a/test/CodeGenCXX/cfi-speculative-vtable.cpp b/test/CodeGenCXX/cfi-speculative-vtable.cpp
new file mode 100644
index 000000000000..490190c4afd7
--- /dev/null
+++ b/test/CodeGenCXX/cfi-speculative-vtable.cpp
@@ -0,0 +1,14 @@
+// Test that we don't emit a bit set entry for a speculative (available_externally) vtable.
+// This does not happen in the Microsoft ABI.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -O1 -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -O1 -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+ virtual ~A();
+};
+
+A a;
+
+// CHECK: @_ZTV1A ={{.*}} available_externally
+// CHECK-NOT: !{{.*}} = !{!{{.*}}, [4 x i8*]* @_ZTV1A, i64 16}
diff --git a/test/CodeGenCXX/cfi-stats.cpp b/test/CodeGenCXX/cfi-stats.cpp
new file mode 100644
index 000000000000..6d0dd5b27091
--- /dev/null
+++ b/test/CodeGenCXX/cfi-stats.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall,cfi-nvcall,cfi-derived-cast,cfi-unrelated-cast,cfi-icall -fsanitize-stats -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall,cfi-nvcall,cfi-derived-cast,cfi-unrelated-cast,cfi-icall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -fsanitize-stats -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: [[STATS:@[^ ]*]] = internal global { i8*, i32, [5 x [2 x i8*]] } { i8* null, i32 5, [5 x [2 x i8*]]
+// CHECK: {{\[\[}}2 x i8*] zeroinitializer,
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 2305843009213693952 to i8*)],
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 4611686018427387904 to i8*)],
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 6917529027641081856 to i8*)],
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 -9223372036854775808 to i8*)]] }
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[CTOR:@[^ ]*]], i8* null }]
+
+struct A {
+ virtual void vf();
+ void nvf();
+};
+struct B : A {};
+
+// CHECK: @vcall
+extern "C" void vcall(A *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 0
+ a->vf();
+}
+
+// CHECK: @nvcall
+extern "C" void nvcall(A *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 1
+ a->nvf();
+}
+
+// CHECK: @dcast
+extern "C" void dcast(A *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 2
+ static_cast<B *>(a);
+}
+
+// CHECK: @ucast
+extern "C" void ucast(void *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 3
+ reinterpret_cast<A *>(a);
+}
+
+// CHECK: @icall
+extern "C" void icall(void (*p)()) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 4
+ p();
+}
+
+// CHECK: define internal void [[CTOR]]()
+// CHECK-NEXT: call void @__sanitizer_stat_init(i8* bitcast ({ i8*, i32, [5 x [2 x i8*]] }* [[STATS]] to i8*))
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/cfi-vcall.cpp b/test/CodeGenCXX/cfi-vcall.cpp
deleted file mode 100644
index daa0531e85d6..000000000000
--- a/test/CodeGenCXX/cfi-vcall.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=NDIAG %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
-// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS --check-prefix=NDIAG %s
-
-// MS: @[[VTA:[0-9]*]] {{.*}} comdat($"\01??_7A@@6B@")
-// MS: @[[VTB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6B0@@")
-// MS: @[[VTAinB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6BA@@@")
-// MS: @[[VTAinC:[0-9]*]] {{.*}} comdat($"\01??_7C@@6B@")
-// MS: @[[VTBinD:[0-9]*]] {{.*}} comdat($"\01??_7D@?A@@6BB@@@")
-// MS: @[[VTAinBinD:[0-9]*]] {{.*}} comdat($"\01??_7D@?A@@6BA@@@")
-// MS: @[[VTFA:[0-9]*]] {{.*}} comdat($"\01??_7FA@?1??foo@@YAXXZ@6B@")
-
-struct A {
- A();
- virtual void f();
-};
-
-struct B : virtual A {
- B();
- virtual void g();
- virtual void h();
-};
-
-struct C : virtual A {
- C();
-};
-
-namespace {
-
-struct D : B, C {
- D();
- virtual void f();
- virtual void h();
-};
-
-}
-
-A::A() {}
-B::B() {}
-C::C() {}
-D::D() {}
-
-void A::f() {
-}
-
-void B::g() {
-}
-
-void D::f() {
-}
-
-void D::h() {
-}
-
-// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}cfi-vcall.cpp\00", align 1
-// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" }
-// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8 } { { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+21]], i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]], i8 0 }
-
-// ITANIUM: define void @_Z2afP1A
-// MS: define void @"\01?af@@YAXPEAUA@@@Z"
-void af(A *a) {
- // ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"_ZTS1A")
- // MS: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"?AUA@@")
- // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]]
- // CHECK-NEXT: {{^$}}
-
- // CHECK: [[TRAPBB]]
- // NDIAG-NEXT: call void @llvm.trap()
- // NDIAG-NEXT: unreachable
- // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64
- // DIAG-ABORT-NEXT: call void @__ubsan_handle_cfi_bad_type_abort(i8* bitcast ({{.*}} @[[BADTYPESTATIC]] to i8*), i64 [[VTINT]])
- // DIAG-ABORT-NEXT: unreachable
- // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_bad_type(i8* bitcast ({{.*}} @[[BADTYPESTATIC]] to i8*), i64 [[VTINT]])
- // DIAG-RECOVER-NEXT: br label %[[CONTBB]]
-
- // CHECK: [[CONTBB]]
- // CHECK: call void %
- a->f();
-}
-
-// ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE
-// MS: define internal void @"\01?df1@@YAXPEAUD@?A@@@Z"
-void df1(D *d) {
- // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
- // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"?AUA@@")
- d->f();
-}
-
-// ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE
-// MS: define internal void @"\01?dg1@@YAXPEAUD@?A@@@Z"
-void dg1(D *d) {
- // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
- // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"?AUB@@")
- d->g();
-}
-
-// ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE
-// MS: define internal void @"\01?dh1@@YAXPEAUD@?A@@@Z"
-void dh1(D *d) {
- // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata ![[DTYPE]])
- // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
- d->h();
-}
-
-// ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE
-// MS: define internal void @"\01?df2@@YAXPEAUD@?A@@@Z"
-__attribute__((no_sanitize("cfi")))
-void df2(D *d) {
- // CHECK-NOT: call i1 @llvm.bitset.test
- d->f();
-}
-
-// ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE
-// MS: define internal void @"\01?df3@@YAXPEAUD@?A@@@Z"
-__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);
- dg1(&d);
- dh1(&d);
- df2(&d);
- df3(&d);
-
- struct FA : A {
- void f() {}
- } fa;
- af(&fa);
-}
-
-namespace test2 {
-
-struct A {
- virtual void m_fn1();
-};
-struct B {
- virtual void m_fn2();
-};
-struct C : B, A {};
-struct D : C {
- void m_fn1();
-};
-
-// ITANIUM: define void @_ZN5test21fEPNS_1DE
-// MS: define void @"\01?f@test2@@YAXPEAUD@1@@Z"
-void f(D *d) {
- // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTSN5test21DE")
- // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"?AUA@test2@@")
- d->m_fn1();
-}
-
-}
-
-// Check for the expected number of elements (9 or 15 respectively).
-// MS: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){8}]]}
-// ITANIUM: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){14}]]}
-
-// ITANIUM-DAG: !{!"_ZTS1A", [3 x i8*]* @_ZTV1A, i64 16}
-// ITANIUM-DAG: !{!"_ZTS1A", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1B", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1A", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64}
-// ITANIUM-DAG: !{!"_ZTS1C", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1A", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1B", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1C", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 88}
-// ITANIUM-DAG: !{![[DTYPE]], [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1A", [7 x i8*]* @_ZTV1B, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1B", [7 x i8*]* @_ZTV1B, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1A", [5 x i8*]* @_ZTV1C, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1C", [5 x i8*]* @_ZTV1C, i64 32}
-// ITANIUM-DAG: !{!"_ZTS1A", [3 x i8*]* @_ZTVZ3foovE2FA, i64 16}
-// ITANIUM-DAG: !{!{{[0-9]+}}, [3 x i8*]* @_ZTVZ3foovE2FA, i64 16}
-
-// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTA]], i64 8}
-// MS-DAG: !{!"?AUB@@", [3 x i8*]* @[[VTB]], i64 8}
-// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTAinB]], i64 8}
-// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTAinC]], i64 8}
-// MS-DAG: !{!"?AUB@@", [3 x i8*]* @[[VTBinD]], i64 8}
-// MS-DAG: !{![[DTYPE]], [3 x i8*]* @[[VTBinD]], i64 8}
-// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTAinBinD]], i64 8}
-// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTFA]], i64 8}
-// MS-DAG: !{!{{[0-9]+}}, [2 x i8*]* @[[VTFA]], i64 8}
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 99be265e2126..0c2193fb07f2 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -343,13 +343,13 @@ 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*], [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" }
+ // 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, i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 5), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i32 0, i32 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*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i64 0, i64 2) }
+ // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, i32 2) }
__attribute__((used))
static nsMemoryImpl sGlobalMemory;
@@ -360,7 +360,7 @@ namespace VirtualMembers {
T t;
};
- // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers13TemplateClassIiEE, i64 0, i64 2), i32 42 }
+ // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, i32 2), i32 42 }
TemplateClass<int> t;
}
diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp
index deb923a70890..f5c9dae7ba4b 100644
--- a/test/CodeGenCXX/const-init.cpp
+++ b/test/CodeGenCXX/const-init.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -std=c++98 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -std=c++11 -o - %s | FileCheck %s
// CHECK: @a = global i32 10
int a = 10;
@@ -27,8 +29,13 @@ C g0 = { C::e1 };
namespace test2 {
struct A {
+#if __cplusplus <= 199711L
static const double d = 1.0;
static const float f = d / 2;
+#else
+ static constexpr double d = 1.0;
+ static constexpr float f = d / 2;
+#endif
static int g();
} a;
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index d7ae220712f8..c78534a218de 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*], [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, i32 0, i32 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*], [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, i32 0, i32 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*], [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, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
// CHECK-NEXT: ret void
B::B(int x) : A(x + 5) {}
}
diff --git a/test/CodeGenCXX/copy-constructor-elim.cpp b/test/CodeGenCXX/copy-constructor-elim.cpp
index d9b28ce30e91..4abe456e4b29 100644
--- a/test/CodeGenCXX/copy-constructor-elim.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck %s -check-prefix MS
// CHECK-NOT: _ZN1CC1ERK1C
// CHECK-NOT: _ZN1SC1ERK1S
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 02feed3208f6..9790ca882c6b 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -24,4 +24,4 @@ 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*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 2) to i32 (...)**)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
index 2f0aa3b3a648..4928c61488e9 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -166,7 +166,7 @@ void f(B b1) {
// 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: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN12rdar138169401AE, i32 0, i32 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
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index 311edaabb5db..7bab11488ad4 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -249,7 +249,7 @@ haslist2::haslist2()
void fn10(int i) {
// CHECK-LABEL: define void @_Z4fn10i
// CHECK: alloca [3 x i32]
- // CHECK: call noalias i8* @_Znw{{[jm]}}
+ // CHECK: call i8* @_Znw{{[jm]}}
// CHECK: store i32 %
// CHECK: store i32 2
// CHECK: store i32 3
diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp
index a3dff79fc494..6a3a394e047a 100644
--- a/test/CodeGenCXX/cxx11-exception-spec.cpp
+++ b/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -70,37 +70,37 @@ void h() {
// CHECK: define {{.*}} @_Z1iv
void i() {
- // CHECK: declare {{.*}} @_Z1gIiEvv() [[NUW]]
+ // CHECK: declare {{.*}} @_Z1gIiEvv() [[NUW2:#[0-9]+]]
g<int>();
// CHECK: declare {{.*}} @_Z1gIA2_iEvv()
// CHECK-NOT: [[NUW]]
g<int[2]>();
- // CHECK: declare {{.*}} @_ZN1SIiE1gEv() [[NUW]]
+ // CHECK: declare {{.*}} @_ZN1SIiE1gEv() [[NUW2]]
S<int>::g();
// CHECK: declare {{.*}} @_ZN1SIA2_iE1gEv()
// CHECK-NOT: [[NUW]]
S<int[2]>::g();
- // CHECK: declare {{.*}} @_Z1gIfEvv() [[NUW]]
+ // CHECK: declare {{.*}} @_Z1gIfEvv() [[NUW2]]
void (*g1)() = &g<float>;
// CHECK: declare {{.*}} @_Z1gIdEvv()
// CHECK-NOT: [[NUW]]
void (*g2)() = &g<double>;
- // CHECK: declare {{.*}} @_ZN1SIfE1gEv() [[NUW]]
+ // CHECK: declare {{.*}} @_ZN1SIfE1gEv() [[NUW2]]
void (*g3)() = &S<float>::g;
// CHECK: declare {{.*}} @_ZN1SIdE1gEv()
// CHECK-NOT: [[NUW]]
void (*g4)() = &S<double>::g;
- // CHECK: declare {{.*}} @_Z1gIA4_cEvv() [[NUW]]
+ // CHECK: declare {{.*}} @_Z1gIA4_cEvv() [[NUW2]]
(void)&g<char[4]>;
// CHECK: declare {{.*}} @_Z1gIcEvv()
// CHECK-NOT: [[NUW]]
(void)&g<char>;
- // CHECK: declare {{.*}} @_ZN1SIA4_cE1gEv() [[NUW]]
+ // CHECK: declare {{.*}} @_ZN1SIA4_cE1gEv() [[NUW2]]
(void)&S<char[4]>::g;
// CHECK: declare {{.*}} @_ZN1SIcE1gEv()
// CHECK-NOT: [[NUW]]
@@ -116,12 +116,15 @@ void j() {
// CHECK: declare {{.*}} @_ZN6NestedIiE1fILb1EcEEvv(
// CHECK-NOT: [[NUW]]
Nested<int>().f<true, char>();
- // CHECK: declare {{.*}} @_ZN6NestedIlE1fILb0ElEEvv({{.*}}) [[NUW]]
+ // CHECK: declare {{.*}} @_ZN6NestedIlE1fILb0ElEEvv({{.*}}) [[NUW2]]
Nested<long>().f<false, long>();
}
// CHECK: attributes [[NONE]] = { {{.*}} }
// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW2]] = { nounwind{{.*}} }
+
+
namespace PR19190 {
template <class T> struct DWFIterator { virtual void get() throw(int) = 0; };
diff --git a/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/test/CodeGenCXX/cxx11-initializer-array-new.cpp
index c662190ff386..59f96031fc40 100644
--- a/test/CodeGenCXX/cxx11-initializer-array-new.cpp
+++ b/test/CodeGenCXX/cxx11-initializer-array-new.cpp
@@ -7,7 +7,7 @@ struct S { S(); S(int); ~S(); int n; };
void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
// CHECK-LABEL: define
-// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 32)
+// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 32)
// CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
// CHECK: store i64 6, i64* %[[COOKIE]]
// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8
@@ -50,7 +50,7 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
// 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)
-// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}})
+// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}})
//
// CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
// CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]]
@@ -113,7 +113,7 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
// No cookie.
// CHECK-NOT: @llvm.uadd.with.overflow
//
-// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}})
+// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}})
//
// CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]*
//
diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
index 8b2ac5eed800..4c1e5a70cbaf 100644
--- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
@@ -21,13 +21,16 @@ int &g() { return r; }
// DARWIN: call cxx_fast_tlscc i32* @_ZTW1r()
// CHECK: ret i32* %{{.*}}
-// LINUX: define weak_odr hidden i32* @_ZTW1r() {
-// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR:#[0-9]+]] {
-// CHECK: call void @_ZTH1r()
+// LINUX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] {
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR1:#[0-9]+]] {
+// LINUX: call void @_ZTH1r()
+// DARWIN: call cxx_fast_tlscc void @_ZTH1r()
// CHECK: load i32*, i32** @r, align 8
// CHECK: ret i32* %{{.*}}
-// CHECK-LABEL: define internal void @__tls_init()
+// LINUX-LABEL: define internal void @__tls_init()
+// DARWIN-LABEL: define internal cxx_fast_tlscc void @__tls_init()
// CHECK: call void @[[R_INIT]]()
-// DARWIN: attributes [[ATTR]] = { nounwind }
+// LINUX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} }
+// DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} }
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
index b5bcc5e23ecd..f465cbdeea84 100644
--- a/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -122,7 +122,8 @@ int f() {
// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE()
// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1VIiE1mE()
-// CHECK: call void @_ZTHN1VIiE1mE()
+// LINUX: call void @_ZTHN1VIiE1mE()
+// DARWIN: call cxx_fast_tlscc void @_ZTHN1VIiE1mE()
// CHECK: ret i32* @_ZN1VIiE1mE
@@ -212,20 +213,25 @@ void set_anon_i() {
// LIUNX: define weak_odr hidden i32* @_ZTW1a() {
// DARWIN: define cxx_fast_tlscc i32* @_ZTW1a()
-// CHECK: call void @_ZTH1a()
+// LINUX: call void @_ZTH1a()
+// DARWIN: call cxx_fast_tlscc void @_ZTH1a()
// CHECK: ret i32* @a
// CHECK: }
-// LINUX: declare extern_weak void @_ZTH1b()
+// LINUX: declare extern_weak void @_ZTH1b() [[ATTR:#[0-9]+]]
// LINUX-LABEL: define internal i32* @_ZTWL1d()
// DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWL1d()
-// CHECK: call void @_ZTHL1d()
+// LINUX: call void @_ZTHL1d()
+// DARWIN: call cxx_fast_tlscc void @_ZTHL1d()
// CHECK: ret i32* @_ZL1d
// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1U1mE()
// DARWIN-LABEL: define cxx_fast_tlscc i32* @_ZTWN1U1mE()
-// CHECK: call void @_ZTHN1U1mE()
+// LINUX: call void @_ZTHN1U1mE()
+// DARWIN: call cxx_fast_tlscc void @_ZTHN1U1mE()
// CHECK: ret i32* @_ZN1U1mE
+
+// LINUX: attributes [[ATTR]] = { {{.+}} }
diff --git a/test/CodeGenCXX/cxx1z-constexpr-if.cpp b/test/CodeGenCXX/cxx1z-constexpr-if.cpp
new file mode 100644
index 000000000000..80a397f51e9a
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used
+
+void should_be_used_1();
+void should_be_used_2();
+void should_not_be_used();
+void f() {
+ if constexpr (false)
+ should_not_be_used();
+ else
+ should_be_used_1();
+
+ if constexpr (true || ({ label: false; }))
+ should_be_used_2();
+ else {
+ goto foo;
+foo: should_not_be_used();
+ }
+}
+
+// CHECK: should_be_used_1
+// CHECK: should_be_used_2
diff --git a/test/CodeGenCXX/cxx1z-init-statement.cpp b/test/CodeGenCXX/cxx1z-init-statement.cpp
new file mode 100644
index 000000000000..5c05212c7247
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-init-statement.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s
+
+typedef int T;
+void f() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[B:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT %[[C:.*]] = icmp slt i32 %[[B]], 8
+ if (int a = 5; a < 8)
+ ;
+}
+
+void f1() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[C:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[B]], align 4
+ // CHECK-NEXT: store i32 7, i32* %[[C]], align 4
+ if (int a, b = 5; int c = 7)
+ ;
+}
+
+int f2() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = call i32 @_Z2f2v()
+ // CHECK-NEXT: store i32 7, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[C:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[D:.*]] = icmp ne i32 %[[C]], 0
+ if (T{f2()}; int c = 7)
+ ;
+ return 2;
+}
+
+void g() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[B:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT: switch i32 %[[B]], label %[[C:.*]] [
+ switch (int a = 5; a) {
+ case 0:
+ break;
+ }
+}
+
+void g1() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[C:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[B]], align 4
+ // CHECK-NEXT: store i32 7, i32* %[[C]], align 4
+ // CHECK-NEXT: %[[D:.*]] = load i32, i32* %[[C]], align 4
+ // CHECK-NEXT: switch i32 %[[D]], label %[[E:.*]] [
+ switch (int a, b = 5; int c = 7) {
+ case 0:
+ break;
+ }
+}
+
+int g2() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = call i32 @_Z2f2v()
+ // CHECK-NEXT: store i32 7, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[C:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT: switch i32 %[[C]], label %[[E:.*]] [
+ switch (T{f2()}; int c = 7) {
+ case 0:
+ break;
+ }
+ return 2;
+}
diff --git a/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp
new file mode 100644
index 000000000000..9110e49f93a1
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -std=c++1z %s -triple x86_64-linux-gnu -fexceptions -fcxx-exceptions -emit-llvm -o - | FileCheck %s
+
+namespace Constant {
+ struct A {
+ int n;
+ char k;
+ ~A();
+ };
+
+ struct B {
+ char k2;
+ };
+
+ struct C : B {};
+
+ struct D : A, C {};
+
+ C c1 = {};
+ C c2 = {1};
+ // CHECK: @_ZN8Constant2c1E = global { i8 } zeroinitializer, align 1
+ // CHECK: @_ZN8Constant2c2E = global { i8 } { i8 1 }, align 1
+
+ // Test packing bases into tail padding.
+ D d1 = {};
+ D d2 = {1, 2, 3};
+ D d3 = {1};
+ // CHECK: @_ZN8Constant2d1E = global { i32, i8, i8 } zeroinitializer, align 4
+ // CHECK: @_ZN8Constant2d2E = global { i32, i8, i8 } { i32 1, i8 2, i8 3 }, align 4
+ // CHECK: @_ZN8Constant2d3E = global { i32, i8, i8 } { i32 1, i8 0, i8 0 }, align 4
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN8Constant1DD1Ev {{.*}} @_ZN8Constant2d1E
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN8Constant1DD1Ev {{.*}} @_ZN8Constant2d2E
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN8Constant1DD1Ev {{.*}} @_ZN8Constant2d3E
+}
+
+namespace Dynamic {
+ struct A {
+ A();
+ A(int);
+ A(const char*, unsigned);
+ ~A();
+ void *p;
+ };
+
+ struct B {
+ ~B();
+ int n = 5;
+ };
+
+ struct C {
+ C(bool = true);
+ };
+
+ int f(), g(), h(), i();
+ struct D : A, B, C {
+ int n = f();
+ };
+
+ D d1 = {};
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call void @_ZN7Dynamic1AC2Ev({{.*}} @_ZN7Dynamic2d1E
+ // CHECK: store i32 5, {{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d1E{{.*}}, i64 8
+ // CHECK: invoke void @_ZN7Dynamic1CC2Eb({{.*}} @_ZN7Dynamic2d1E{{.*}}, i1 zeroext true)
+ // CHECK: unwind label %[[UNWIND:.*]]
+ // CHECK: invoke i32 @_ZN7Dynamic1fEv()
+ // CHECK: unwind label %[[UNWIND:.*]]
+ // CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @_ZN7Dynamic2d1E, i32 0, i32 2
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN7Dynamic1DD1Ev {{.*}} @_ZN7Dynamic2d1E
+ // CHECK: ret
+ //
+ // UNWIND:
+ // CHECK: call void @_ZN7Dynamic1BD1Ev({{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d1E{{.*}}, i64 8
+ // CHECK: call void @_ZN7Dynamic1AD1Ev({{.*}} @_ZN7Dynamic2d1E
+
+ D d2 = {1, 2, false};
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call void @_ZN7Dynamic1AC1Ei({{.*}} @_ZN7Dynamic2d2E{{.*}}, i32 1)
+ // CHECK: store i32 2, {{.*}}i8* getelementptr inbounds {{.*}}@_ZN7Dynamic2d2E{{.*}}, i64 8
+ // CHECK: invoke void @_ZN7Dynamic1CC1Eb({{.*}} @_ZN7Dynamic2d2E{{.*}}, i1 zeroext false)
+ // CHECK: invoke i32 @_ZN7Dynamic1fEv()
+ // CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @_ZN7Dynamic2d2E, i32 0, i32 2
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN7Dynamic1DD1Ev {{.*}} @_ZN7Dynamic2d2E
+ // CHECK: ret void
+
+ D d3 = {g(), h(), {}, i()};
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: %[[G_CALL:.*]] = call i32 @_ZN7Dynamic1gEv()
+ // CHECK: call void @_ZN7Dynamic1AC1Ei({{.*}} @_ZN7Dynamic2d3E{{.*}}, i32 %[[G_CALL]])
+ // CHECK: %[[H_CALL:.*]] = invoke i32 @_ZN7Dynamic1hEv()
+ // CHECK: unwind label %[[DESTROY_A_LPAD:.*]]
+ // CHECK: store i32 %[[H_CALL]], {{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d3E{{.*}}, i64 8
+ // CHECK: invoke void @_ZN7Dynamic1CC2Eb({{.*}} @_ZN7Dynamic2d3E{{.*}}, i1 zeroext true)
+ // CHECK: unwind label %[[DESTROY_AB_LPAD:.*]]
+ // CHECK: %[[I_CALL:.*]] = invoke i32 @_ZN7Dynamic1iEv()
+ // CHECK: unwind label %[[DESTROY_AB_LPAD:.*]]
+ // CHECK: store i32 %[[I_CALL]], i32* getelementptr {{.*}} @_ZN7Dynamic2d3E, i32 0, i32 2
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN7Dynamic1DD1Ev {{.*}} @_ZN7Dynamic2d3E to i8*
+ // CHECK: ret
+ //
+ // DESTROY_A_LPAD:
+ // CHECK: br label %[[A_CLEANUP:.*]]
+ //
+ // DESTROY_B_LPAD:
+ // CHECK: call void @_ZN7Dynamic1BD1Ev({{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d3E{{.*}}, i64 8
+ // CHECK: br label %[[A_CLEANUP:.*]]
+ //
+ // A_CLEANUP:
+ // CHECK: call void @_ZN7Dynamic1AD1Ev({{.*}} @_ZN7Dynamic2d3E
+}
diff --git a/test/CodeGenCXX/cxx1z-inline-variables.cpp b/test/CodeGenCXX/cxx1z-inline-variables.cpp
new file mode 100644
index 000000000000..183709373d12
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
+
+struct Q {
+ // CHECK: @_ZN1Q1kE = linkonce_odr constant i32 5, comdat
+ static constexpr int k = 5;
+};
+const int &r = Q::k;
+
+int f();
+
+// const does not imply internal linkage.
+// CHECK: @external_inline = linkonce_odr constant i32 5, comdat
+inline const int external_inline = 5;
+const int &use1 = external_inline;
+
+// static still does, though.
+// CHECK: @_ZL15internal_inline = internal constant i32 5
+static inline const int internal_inline = 5;
+const int &use2 = internal_inline;
+
+int a = f();
+// CHECK: @b = linkonce_odr global i32 0, comdat
+// CHECK: @_ZGV1b = linkonce_odr global i64 0, comdat($b)
+inline int b = f();
+int c = f();
+
+// For compatibility with C++11 and C++14, an out-of-line declaration of a
+// static constexpr local variable promotes the variable to weak_odr.
+struct compat {
+ static constexpr int a = 1;
+ static constexpr int b = 2;
+ static constexpr int c = 3;
+ static inline constexpr int d = 4;
+};
+const int &compat_use_before_redecl = compat::b;
+const int compat::a;
+const int compat::b;
+const int compat::c;
+const int compat::d;
+const int &compat_use_after_redecl1 = compat::c;
+const int &compat_use_after_redecl2 = compat::d;
+// CHECK: @_ZN6compat1bE = weak_odr constant i32 2
+// CHECK: @_ZN6compat1aE = weak_odr constant i32 1
+// CHECK: @_ZN6compat1cE = weak_odr constant i32 3
+// CHECK: @_ZN6compat1dE = linkonce_odr constant i32 4
+
+template<typename T> struct X {
+ static int a;
+ static inline int b;
+ static int c;
+};
+// CHECK: @_ZN1XIiE1aE = linkonce_odr global i32 10
+// CHECK: @_ZN1XIiE1bE = global i32 20
+// CHECK-NOT: @_ZN1XIiE1cE
+template<> inline int X<int>::a = 10;
+int &use3 = X<int>::a;
+template<> int X<int>::b = 20;
+template<> inline int X<int>::c = 30;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: call i32 @_Z1fv
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: comdat
+// CHECK-SAME: {{$}}
+// CHECK: load atomic {{.*}} acquire
+// CHECK: br
+// CHECK: __cxa_guard_acquire(i64* @_ZGV1b)
+// CHECK: br
+// CHECK: call i32 @_Z1fv
+// CHECK: __cxa_guard_release(i64* @_ZGV1b)
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: call i32 @_Z1fv
+
+template<typename T> inline int d = f();
+int e = d<int>;
+
+// CHECK-LABEL: define {{.*}}global_var_init{{.*}}comdat
+// CHECK: _ZGV1dIiE
+// CHECK-NOT: __cxa_guard_acquire(i64* @_ZGV1b)
+// CHECK: call i32 @_Z1fv
+// CHECK-NOT: __cxa_guard_release(i64* @_ZGV1b)
diff --git a/test/CodeGenCXX/cxx1z-lambda-star-this.cpp b/test/CodeGenCXX/cxx1z-lambda-star-this.cpp
new file mode 100644
index 000000000000..a7e4aadbd573
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-lambda-star-this.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++1y -triple i686-pc-windows-msvc -emit-llvm %s -o - | FileCheck %s
+//CHECK: %[[A_LAMBDA:.*]] = type { %struct.A }
+//CHECK: %[[B_LAMBDA:.*]] = type { %struct.B* }
+struct A {
+ double a = 111;
+ auto foo() { return [*this] { return a; }; }
+};
+
+namespace ns1 {
+int X = A{}.foo()();
+} //end ns1
+
+//CHECK: @"\01?foo@A@@QAE?A?<auto>@@XZ"(%struct.A* %this, %class.anon* noalias sret %[[A_LAMBDA_RETVAL:.*]])
+// get the first object with the closure type, which is of type 'struct.A'
+//CHECK: %[[I0:.+]] = getelementptr inbounds %[[A_LAMBDA]], %[[A_LAMBDA]]* %[[A_LAMBDA_RETVAL]], i32 0, i32 0
+//CHECK: %[[I1:.+]] = bitcast %struct.A* %[[I0]] to i8*
+//CHECK: %[[I2:.+]] = bitcast %struct.A* %this1 to i8*
+// copy the contents ...
+//CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[I1]], i8* %[[I2]], i32 8, i32 8, i1 false)
+
+struct B {
+ double b = 222;
+ auto bar() { return [this] { return b; }; };
+};
+
+namespace ns2 {
+int X = B{}.bar()();
+}
+//CHECK: @"\01?bar@B@@QAE?A?<auto>@@XZ"(%struct.B* %this, %class.anon.0* noalias sret %agg.result)
+//CHECK: %[[I20:.+]] = getelementptr inbounds %class.anon.0, %class.anon.0* %agg.result, i32 0, i32 0
+//CHECK: store %struct.B* %this1, %struct.B** %[[I20]], align 4
diff --git a/test/CodeGenCXX/debug-info-access.cpp b/test/CodeGenCXX/debug-info-access.cpp
index 1699bab96104..41b7f71fcecb 100644
--- a/test/CodeGenCXX/debug-info-access.cpp
+++ b/test/CodeGenCXX/debug-info-access.cpp
@@ -1,13 +1,16 @@
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple %itanium_abi_triple %s -o - | FileCheck %s
// Test the various accessibility flags in the debug info.
struct A {
+ // CHECK: ![[A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A",
+
// CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
void pub_default();
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "pub_default_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagStaticMember)
static int pub_default_static;
};
-// CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: !"_ZTS1A",{{.*}} flags: DIFlagPublic)
+
+// CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: ![[A]],{{.*}} flags: DIFlagPublic)
class B : public A {
public:
// CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagPrototyped,
diff --git a/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/test/CodeGenCXX/debug-info-anon-union-vars.cpp
index 5b0370eb749d..b844d429447b 100644
--- a/test/CodeGenCXX/debug-info-anon-union-vars.cpp
+++ b/test/CodeGenCXX/debug-info-anon-union-vars.cpp
@@ -44,8 +44,8 @@ void instantiate(int x) {
buildBytes(x);
}
-// 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: "c",{{.*}} file: [[FILE:.*]], line: 6,{{.*}} isLocal: true, isDefinition: true
+// CHECK: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp",
// 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
@@ -56,7 +56,7 @@ void instantiate(int x) {
// CHECK: !DILocalVariable(
// CHECK-NOT: name:
// CHECK: type: ![[UNION:[0-9]+]]
-// CHECK: ![[UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-NOT: name:
// CHECK: elements
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
diff --git a/test/CodeGenCXX/debug-info-artificial-arg.cpp b/test/CodeGenCXX/debug-info-artificial-arg.cpp
index c840df672aa0..a0cf131f83e1 100644
--- a/test/CodeGenCXX/debug-info-artificial-arg.cpp
+++ b/test/CodeGenCXX/debug-info-artificial-arg.cpp
@@ -22,11 +22,10 @@ int main(int argc, char **argv) {
A reallyA (500);
}
-// CHECK: ![[CLASSTYPE:.*]] = !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK: ![[CLASSTYPE:.*]] = distinct !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: ![[ARTARG:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[CLASSTYPE]],{{.*}} DIFlagArtificial
+// CHECK: !DISubprogram(name: "A", scope: ![[CLASSTYPE]]
// CHECK-SAME: line: 12
// CHECK-SAME: DIFlagPublic
// CHECK: !DISubroutineType(types: [[FUNCTYPE:![0-9]*]])
diff --git a/test/CodeGenCXX/debug-info-calling-conventions.cpp b/test/CodeGenCXX/debug-info-calling-conventions.cpp
new file mode 100644
index 000000000000..51d801e35ef6
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-calling-conventions.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+
+struct A {
+ void thiscallcc();
+};
+void A::thiscallcc() {}
+
+// CHECK: !DISubprogram(name: "thiscallcc", {{.*}} type: ![[thiscallty:[^,]*]], {{.*}})
+// CHECK: ![[thiscallty]] = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: ![[thisargs:[^,)]*]])
+// CHECK: ![[thisargs]] = !{null, ![[thisptrty:[^,}]*]]}
+// CHECK: ![[thisptrty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{.*}}, size: 32, align: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
+
+void cdeclcc() {}
+void __fastcall fastcallcc() {}
+void __stdcall stdcallcc() {}
+void __vectorcall vectorcallcc() {}
+
+// CHECK: !DISubprogram(name: "cdeclcc", {{.*}} type: ![[cdeclty:[^,]*]], {{.*}})
+// CHECK: ![[cdeclty]] = !DISubroutineType(types: ![[noargs:[^,)]*]])
+// CHECK: ![[noargs]] = !{null}
+// CHECK: !DISubprogram(name: "fastcallcc", {{.*}} type: ![[fastcallty:[^,]*]], {{.*}})
+// CHECK: ![[fastcallty]] = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: ![[noargs]])
+// CHECK: !DISubprogram(name: "stdcallcc", {{.*}} type: ![[stdcallty:[^,]*]], {{.*}})
+// CHECK: ![[stdcallty]] = !DISubroutineType(cc: DW_CC_BORLAND_stdcall, types: ![[noargs]])
+// CHECK: !DISubprogram(name: "vectorcallcc", {{.*}} type: ![[vectorcallty:[^,]*]], {{.*}})
+// CHECK: ![[vectorcallty]] = !DISubroutineType(cc: DW_CC_LLVM_vectorcall, types: ![[noargs]])
diff --git a/test/CodeGenCXX/debug-info-class-limited-plugin.test b/test/CodeGenCXX/debug-info-class-limited-plugin.test
index 61d258d9ffc4..533c2f6b16c5 100644
--- a/test/CodeGenCXX/debug-info-class-limited-plugin.test
+++ b/test/CodeGenCXX/debug-info-class-limited-plugin.test
@@ -1,2 +1,2 @@
-RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -g -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-function-names %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
+RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-function-names %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
REQUIRES: plugins, examples
diff --git a/test/CodeGenCXX/debug-info-class-limited.test b/test/CodeGenCXX/debug-info-class-limited.test
index 0b10728f3c97..c2e332866f9f 100644
--- a/test/CodeGenCXX/debug-info-class-limited.test
+++ b/test/CodeGenCXX/debug-info-class-limited.test
@@ -1 +1 @@
-RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -g %S/Inputs/debug-info-class-limited.cpp -o - | FileCheck %S/Inputs/debug-info-class-limited.cpp
+RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %S/Inputs/debug-info-class-limited.cpp -o - | FileCheck %S/Inputs/debug-info-class-limited.cpp
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
index a63efe5d780a..d03c0845dd6b 100644
--- a/test/CodeGenCXX/debug-info-class.cpp
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -83,13 +83,22 @@ int main(int argc, char **argv) {
return 0;
}
-// RUN: %clang -target x86_64-unknown_unknown -emit-llvm -g -S %s -o - | FileCheck %s
-// RUN: %clang -target i686-cygwin -emit-llvm -g -S %s -o - | FileCheck %s
-// RUN: %clang -target armv7l-unknown-linux-gnueabihf -emit-llvm -g -S %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions %s -o - | FileCheck %s
// CHECK: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
// CHECK-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
// CHECK: store i32 0, i32* %{{.+}}, !dbg ![[RETLOC:.*]]
+
+// 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: "I"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
// 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"
@@ -99,12 +108,10 @@ int main(int argc, char **argv) {
// 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: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
-// CHECK-SAME: vtableHolder: !"_ZTS1C"
+// CHECK-SAME: vtableHolder: [[C]]
// CHECK-SAME: identifier: "_ZTS1C"
// CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_S:![0-9]*]], [[C_DTOR:![0-9]*]]}
// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C"
@@ -114,39 +121,33 @@ int main(int argc, char **argv) {
// CHECK-SAME: DIFlagStaticMember
// CHECK: [[C_DTOR]] = !DISubprogram(name: "~C"
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "D"
+// CHECK: [[D:![0-9]+]] = !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: !DISubprogram(name: "func",{{.*}} scope: [[D]]
+// CHECK-SAME: isDefinition: true
+// CHECK-SAME: declaration: [[D_FUNC_DECL:![0-9]*]]
+// CHECK: [[D_FUNC_DECL]] = !DISubprogram(name: "func",{{.*}} scope: [[D]]
+// CHECK-SAME: isDefinition: false
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "inner",{{.*}} line: 50
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: elements: [[G_INNER_MEM:![0-9]*]]
// CHECK-SAME: identifier: "_ZTSN1G5innerE"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "G"
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS1G"
// CHECK: [[G_INNER_MEM]] = !{[[G_INNER_I:![0-9]*]]}
// 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: !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-codeview-display-name.cpp b/test/CodeGenCXX/debug-info-codeview-display-name.cpp
index 1d0300c76c01..b1b5a1e9acb8 100644
--- a/test/CodeGenCXX/debug-info-codeview-display-name.cpp
+++ b/test/CodeGenCXX/debug-info-codeview-display-name.cpp
@@ -1,14 +1,22 @@
-// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98 | \
-// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | FileCheck %s
+// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
+// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
+// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
+// RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
+// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
+// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=QUAL
void freefunc() { }
// CHECK-DAG: "freefunc"
namespace N {
int b() { return 0; }
-// CHECK-DAG: "N::b"
+// UNQUAL-DAG: "b"
+// QUAL-DAG: "N::b"
namespace { void func() { } }
-// CHECK-DAG: "N::`anonymous namespace'::func
+// UNQUAL-DAG: "func"
+// QUAL-DAG: "N::`anonymous namespace'::func"
}
void _c(void) {
@@ -19,19 +27,24 @@ void _c(void) {
struct foo {
int operator+(int);
foo(){}
-// CHECK-DAG: "foo::foo"
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
~foo(){}
-// CHECK-DAG: "foo::~foo"
+// UNQUAL-DAG: "~foo"
+// QUAL-DAG: "foo::~foo"
foo(int i){}
-// CHECK-DAG: "foo::foo"
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
foo(char *q){}
-// CHECK-DAG: "foo::foo"
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
static foo* static_method() { return 0; }
-// CHECK-DAG: "foo::static_method"
+// UNQUAL-DAG: "static_method"
+// QUAL-DAG: "foo::static_method"
};
@@ -40,7 +53,8 @@ void use_foo() {
foo::static_method();
}
-// CHECK-DAG: "foo::operator+"
+// UNQUAL-DAG: "operator+"
+// QUAL-DAG: "foo::operator+"
int foo::operator+(int a) { return a; }
// PR17371
@@ -60,14 +74,20 @@ void OverloadedNewDelete::operator delete(void *) { }
void OverloadedNewDelete::operator delete[](void *) { }
int OverloadedNewDelete::operator+(int x) { return x; };
-// CHECK-DAG: "OverloadedNewDelete::operator new"
-// CHECK-DAG: "OverloadedNewDelete::operator new[]"
-// CHECK-DAG: "OverloadedNewDelete::operator delete"
-// CHECK-DAG: "OverloadedNewDelete::operator delete[]"
-// CHECK-DAG: "OverloadedNewDelete::operator+"
+// UNQUAL-DAG: "operator new"
+// UNQUAL-DAG: "operator new[]"
+// UNQUAL-DAG: "operator delete"
+// UNQUAL-DAG: "operator delete[]"
+// UNQUAL-DAG: "operator+"
+// QUAL-DAG: "OverloadedNewDelete::operator new"
+// QUAL-DAG: "OverloadedNewDelete::operator new[]"
+// QUAL-DAG: "OverloadedNewDelete::operator delete"
+// QUAL-DAG: "OverloadedNewDelete::operator delete[]"
+// QUAL-DAG: "OverloadedNewDelete::operator+"
-template <void (*)(void)>
+
+template <typename T, void (*)(void)>
void fn_tmpl() {}
-template void fn_tmpl<freefunc>();
-// CHECK-DAG: "fn_tmpl"
+template void fn_tmpl<int, freefunc>();
+// CHECK-DAG: "fn_tmpl<int,&freefunc>"
diff --git a/test/CodeGenCXX/debug-info-cxx1y.cpp b/test/CodeGenCXX/debug-info-cxx1y.cpp
index 37f95959911c..faf29d3ed11b 100644
--- a/test/CodeGenCXX/debug-info-cxx1y.cpp
+++ b/test/CodeGenCXX/debug-info-cxx1y.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -std=c++14 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
// CHECK: [[EMPTY:![0-9]*]] = !{}
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
+// CHECK: [[FOO:![0-9]+]] = distinct !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: !DISubprogram(name: "func", {{.*}} scope: !"_ZTS3foo"
+// CHECK: !DISubprogram(name: "func", {{.*}} scope: [[FOO]]
// CHECK-SAME: type: [[SUBROUTINE_TYPE:![0-9]*]]
// CHECK-SAME: isDefinition: true
// CHECK-SAME: declaration: [[FUNC_DECL:![0-9]*]]
@@ -12,7 +12,7 @@
// CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]}
// CHECK: [[INT]] = !DIBasicType(name: "int"
// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func",
-// CHECK-SAME: scope: !"_ZTS3foo"
+// CHECK-SAME: scope: [[FOO]]
// CHECK-SAME: type: [[SUBROUTINE_TYPE]]
// CHECK-SAME: isDefinition: false
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index 71e6e2b2574e..44daf412d3ac 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -4,6 +4,7 @@ enum class A { A1=1 }; // underlying type is int by default
enum class B: unsigned long { B1=1 }; // underlying type is unsigned long
enum C { C1 = 1 };
enum D : short; // enum forward declaration
+enum Z : int;
A a;
B b;
C c;
@@ -94,12 +95,17 @@ void f2(E) {
// CHECK-NOT: offset:
// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Z"
+// CHECK-NOT: scope:
+// CHECK-SAME: flags: DIFlagFwdDecl
+void fz() { Z z; }
+
namespace test5 {
+// CHECK: [[TEST5:![0-9]+]] = !DINamespace(name: "test5"
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
-// CHECK-SAME: scope: [[TEST5:![0-9]+]]
+// CHECK-SAME: scope: [[TEST5]]
// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK-SAME: identifier: "_ZTSN5test51EE"
-// CHECK: [[TEST5]] = !DINamespace(name: "test5"
enum E : int;
void f1(E *) {
}
diff --git a/test/CodeGenCXX/debug-info-function-context.cpp b/test/CodeGenCXX/debug-info-function-context.cpp
index 24f9f1bda639..1db62d96d5b6 100644
--- a/test/CodeGenCXX/debug-info-function-context.cpp
+++ b/test/CodeGenCXX/debug-info-function-context.cpp
@@ -26,11 +26,12 @@ int global_namespace_variable = 1;
// function has the file as a context.
// CHECK: ![[FILE:[0-9]+]] = !DIFile(filename: "{{.*}}context.cpp",
-// CHECK: !DISubprogram(name: "member_function",{{.*}} scope: !"_ZTS1C",{{.*}} isDefinition: true
+// CHECK: ![[C:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
+// CHECK: ![[NS:.*]] = !DINamespace(name: "ns"
+// CHECK: !DISubprogram(name: "member_function",{{.*}} scope: ![[C]],{{.*}} isDefinition: true
-// CHECK: !DISubprogram(name: "static_member_function",{{.*}} scope: !"_ZTS1C",{{.*}} isDefinition: true
+// CHECK: !DISubprogram(name: "static_member_function",{{.*}} scope: ![[C]],{{.*}} isDefinition: true
// CHECK: !DISubprogram(name: "global_function",{{.*}} scope: ![[FILE]],{{.*}} isDefinition: true
-// CHECK: !DISubprogram(name: "global_namespace_function",{{.*}} scope: ![[NS:[0-9]+]],{{.*}} isDefinition: true
-// CHECK: ![[NS]] = !DINamespace(name: "ns"
+// CHECK: !DISubprogram(name: "global_namespace_function",{{.*}} scope: ![[NS]],{{.*}} isDefinition: true
diff --git a/test/CodeGenCXX/debug-info-global.cpp b/test/CodeGenCXX/debug-info-global.cpp
index 920db82409bc..795602380d20 100644
--- a/test/CodeGenCXX/debug-info-global.cpp
+++ b/test/CodeGenCXX/debug-info-global.cpp
@@ -15,7 +15,7 @@ int f1() {
// CHECK: [[GLOBALS]] = !{[[CNST:![0-9]*]]}
-// CHECK: [[CNST]] = !DIGlobalVariable(name: "cnst",
-// CHECK-SAME: scope: [[NS:![0-9]*]]
+// CHECK: [[CNST]] = distinct !DIGlobalVariable(name: "cnst",
+// CHECK-SAME: scope: [[NS:![0-9]*]]
// CHECK: [[NS]] = !DINamespace(name: "ns"
diff --git a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
index 19f8d01e1ab6..70b233cac4dc 100644
--- a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
+++ b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
@@ -9,9 +9,10 @@ struct Bar {
int i1;
// 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: line: [[@LINE+4]]
+ // CHECK-SAME: baseType: ![[UNION:[0-9]+]]
// CHECK-SAME: size: 32, align: 32, offset: 32
+ // CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,{{.*}} identifier: "_ZTSN3BarUt_E")
union {
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i2",
// CHECK-SAME: line: [[@LINE+5]]
diff --git a/test/CodeGenCXX/debug-info-limited.cpp b/test/CodeGenCXX/debug-info-limited.cpp
index b209e3a850de..4467d20f3de4 100644
--- a/test/CodeGenCXX/debug-info-limited.cpp
+++ b/test/CodeGenCXX/debug-info-limited.cpp
@@ -1,4 +1,5 @@
// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s
+// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck --check-prefix=CHECK-C %s
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A"
// CHECK-NOT: DIFlagFwdDecl
@@ -27,8 +28,8 @@ int baz(B *b) {
}
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "C"
-// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-C: !DICompositeType(tag: DW_TAG_structure_type, name: "C"
+// CHECK-C-SAME: flags: DIFlagFwdDecl
struct C {
};
diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp
index 29806351c94c..b3f9c32e0911 100644
--- a/test/CodeGenCXX/debug-info-line-if.cpp
+++ b/test/CodeGenCXX/debug-info-line-if.cpp
@@ -15,7 +15,7 @@ int main() {
// CHECK: br label
// CHECK: br label
- // CHECK: br label {{.*}}, !dbg [[DBG1:!.*]]
+ // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]]
#line 200
while (a)
@@ -25,7 +25,7 @@ int main() {
++a; // CHECK: add nsw{{.*}}, 1
// CHECK: br label
- // CHECK: br label {{.*}}, !dbg [[DBG2:!.*]]
+ // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]]
#line 300
for (; a; )
@@ -35,7 +35,7 @@ int main() {
++a; // CHECK: add nsw{{.*}}, 1
// CHECK: br label
- // CHECK: br label {{.*}}, !dbg [[DBG3:!.*]]
+ // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]]
#line 400
int x[] = {1, 2};
@@ -46,10 +46,22 @@ int main() {
++a; // CHECK: add nsw{{.*}}, 1
// CHECK: br label
- // CHECK: br label {{.*}}, !dbg [[DBG4:!.*]]
+ // CHECK: br label {{.*}}, !dbg [[DBG4:![0-9]*]], !llvm.loop [[L4:![0-9]*]]
- // CHECK: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}})
- // CHECK: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}})
- // CHECK: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}})
- // CHECK: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}})
+ // CHECK-DAG: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}})
+ // CHECK-DAG: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}})
+ // CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}})
+ // CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}})
+
+ // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[LDBG1:![0-9]*]]}
+ // CHECK-DAG: [[LDBG1]] = !DILocation(line: 100, scope: !{{.*}})
+
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]}
+ // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}})
+
+ // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]}
+ // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}})
+
+ // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]}
+ // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}})
}
diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp
index 9fb6ba8ac70e..11653040109c 100644
--- a/test/CodeGenCXX/debug-info-line.cpp
+++ b/test/CodeGenCXX/debug-info-line.cpp
@@ -1,8 +1,6 @@
-// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s
// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s
-// XFAIL: win32
-
int &src();
int *sink();
extern "C" __complex float complex_src();
diff --git a/test/CodeGenCXX/debug-info-member-call.cpp b/test/CodeGenCXX/debug-info-member-call.cpp
new file mode 100644
index 000000000000..3b5adb8e4b82
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-member-call.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=standalone -dwarf-column-info %s -o - | FileCheck %s
+void ext();
+
+struct Bar {
+ void bar() { ext(); }
+};
+
+struct Foo {
+ Bar *b;
+
+ Bar *foo() { return b; }
+};
+
+void test(Foo *f) {
+ f->foo()->bar();
+}
+
+// CHECK-LABEL: @_Z4testP3Foo
+// CHECK: call {{.*}} @_ZN3Foo3fooEv{{.*}}, !dbg ![[CALL1LOC:.*]]
+// CHECK: call void @_ZN3Bar3barEv{{.*}}, !dbg ![[CALL2LOC:.*]]
+
+// CHECK: ![[CALL1LOC]] = !DILocation(line: [[LINE:[0-9]+]], column: 6,
+// CHECK: ![[CALL2LOC]] = !DILocation(line: [[LINE]], column: 13,
+
diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp
index bdd14e0b735d..73d8b928269a 100644
--- a/test/CodeGenCXX/debug-info-method.cpp
+++ b/test/CodeGenCXX/debug-info-method.cpp
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -debug-info-kind=limited %s -o - | FileCheck %s
-// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A",{{.*}} identifier: "_ZTS1A")
+// CHECK: ![[A:[0-9]+]] = distinct !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: ![[THISTYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[A]]
// 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: ![[MEMFUNTYPE]] = !DISubroutineType({{(cc: DW_CC_BORLAND_thiscall, )?}}types: ![[MEMFUNARGS:[0-9]+]])
// CHECK: ![[MEMFUNARGS]] = {{.*}}, ![[THISTYPE]],
// CHECK: !DILocalVariable(name: "this", arg: 1
// CHECK: !DILocalVariable(arg: 2
diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp
new file mode 100644
index 000000000000..a146ce94176e
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+
+// Tests that certain miscellaneous features work in the MS ABI.
+
+struct Foo {
+ virtual void f();
+ virtual void g();
+ virtual void h();
+ struct Nested {};
+};
+Foo f;
+Foo::Nested n;
+
+// CHECK: ![[Foo:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo",
+// CHECK-SAME: identifier: ".?AUFoo@@"
+
+// CHECK: !DISubprogram(name: "f",
+// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0,
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+
+// CHECK: !DISubprogram(name: "g",
+// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 1,
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+
+// CHECK: !DISubprogram(name: "h",
+// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 2,
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
+// CHECK-SAME: identifier: ".?AUNested@Foo@@"
diff --git a/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp b/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp
new file mode 100644
index 000000000000..cef1eb8c5a09
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+typedef struct {
+} test1;
+
+test1 gv1;
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "test1"
+
+struct {
+} test2;
+void *use_test2 = &test2;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "<unnamed-type-test2>"
+
+typedef struct {
+} *test3;
+test3 gv3;
+void *use_test3 = &gv3;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "<unnamed-type-test3>"
diff --git a/test/CodeGenCXX/debug-info-ms-bitfields.cpp b/test/CodeGenCXX/debug-info-ms-bitfields.cpp
new file mode 100644
index 000000000000..07d4c0c6c78a
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ms-bitfields.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+#pragma pack(1)
+struct S {
+ char : 8;
+ short : 8;
+ short x : 8;
+} s;
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, align: 16, offset: 16, flags: DIFlagBitField, extraData: i64 8)
diff --git a/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp b/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp
new file mode 100644
index 000000000000..4b9f2a146896
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-windows -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+// Test member pointer inheritance models.
+
+struct A { int a; };
+struct B { int b; };
+struct C : A, B { int c; };
+struct D : virtual C { int d; };
+struct E;
+int A::*pmd_a;
+int C::*pmd_b;
+int D::*pmd_c;
+int E::*pmd_d;
+void (A::*pmf_a)();
+void (C::*pmf_b)();
+void (D::*pmf_c)();
+void (E::*pmf_d)();
+
+// Test incomplete MPTs, which don't have inheritance models.
+
+struct Incomplete;
+int Incomplete::**ppmd;
+void (Incomplete::**ppmf)();
+
+// CHECK: distinct !DIGlobalVariable(name: "pmd_a", {{.*}} type: ![[pmd_a:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagSingleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmd_b", {{.*}} type: ![[pmd_b:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_b]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagMultipleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmd_c", {{.*}} type: ![[pmd_c:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_c]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 64, flags: DIFlagVirtualInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmd_d", {{.*}} type: ![[pmd_d:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_d]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 96,
+// CHECK-NOT: flags:
+// CHECK-SAME: ){{$}}
+
+// CHECK: distinct !DIGlobalVariable(name: "pmf_a", {{.*}} type: ![[pmf_a:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 64, flags: DIFlagSingleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmf_b", {{.*}} type: ![[pmf_b:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_b]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 128, flags: DIFlagMultipleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmf_c", {{.*}} type: ![[pmf_c:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_c]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 128, flags: DIFlagVirtualInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmf_d", {{.*}} type: ![[pmf_d:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_d]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 192,
+// CHECK-NOT: flags:
+// CHECK-SAME: ){{$}}
+
+// CHECK: distinct !DIGlobalVariable(name: "ppmd", {{.*}} type: ![[ppmd:[^, ]*]], {{.*}})
+// CHECK: ![[ppmd]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmd2:[^ ]*]], size: 64, align: 64)
+// CHECK: ![[ppmd2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}}
+// CHECK: distinct !DIGlobalVariable(name: "ppmf", {{.*}} type: ![[ppmf:[^, ]*]], {{.*}})
+// CHECK: ![[ppmf]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmf2:[^ ]*]], size: 64, align: 64)
+// CHECK: ![[ppmf2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}}
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index 4933ae967452..060a5cea636c 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -57,57 +57,57 @@ void B::func_fwd() {}
// CHECK: [[CU:![0-9]+]] = distinct !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: [[I:![0-9]+]] = distinct !DIGlobalVariable(name: "i",{{.*}} scope: [[NS:![0-9]+]],
+// CHECK: [[NS]] = !DINamespace(name: "B", scope: [[CTXT:![0-9]+]], file: [[FOOCPP:![0-9]+]], line: 1)
+// CHECK: [[FOOCPP]] = !DIFile(filename: "foo.cpp"
// 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]+]] = distinct !DISubprogram(name: "f1",{{.*}} line: 4
-// CHECK-SAME: isDefinition: true
-// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} isDefinition: true
-// CHECK: [[FUNC_FWD:![0-9]+]] = distinct !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: [[VAR_FWD:![0-9]+]] = distinct !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]] = !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: [[LEX1]] = distinct !DILexicalBlock(scope: [[FUNC:![0-9]+]], file: [[FOOCPP]],
+
+// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} isDefinition: true
+// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT:![0-9]+]],
+// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], line: 27)
+// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
+// CHECK-SAME: line: 5
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK: [[M7]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAR:![0-9]+]]
+// CHECK: [[BAR]] = !DICompositeType(tag: DW_TAG_structure_type, name: "bar",
+// CHECK-SAME: line: 6
+// CHECK-SAME: DIFlagFwdDecl
+
+// CHECK: [[M8]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[F1:![0-9]+]]
+// CHECK: [[F1:![0-9]+]] = distinct !DISubprogram(name: "f1",{{.*}} line: 4
+// CHECK-SAME: isDefinition: true
// 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-SAME: baseType: [[BAR]]
// 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: [[VAR_DECL]] = !DIGlobalVariable(name: "var_decl", linkageName: "{{[^"]*var_decl[^"]*}}", 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: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 47,{{.*}} isDefinition: true
// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
// CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit(
-// CHECK-GMLT-SAME: emissionKind: 2,
+// CHECK-GMLT-SAME: emissionKind: LineTablesOnly,
// CHECK-GMLT-NOT: imports:
// CHECK-NOLIMIT: !DICompositeType(tag: DW_TAG_structure_type, name: "bar",{{.*}} line: 6,
// CHECK-NOLIMIT-NOT: DIFlagFwdDecl
// CHECK-NOLIMIT-SAME: ){{$}}
-
-// REQUIRES: dw2
diff --git a/test/CodeGenCXX/debug-info-nodebug.cpp b/test/CodeGenCXX/debug-info-nodebug.cpp
new file mode 100644
index 000000000000..9f140efaed6f
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-nodebug.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -DSETNODEBUG=0 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=YESINFO
+// RUN: %clang_cc1 -DSETNODEBUG=1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=NOINFO
+
+#if SETNODEBUG
+#define NODEBUG __attribute__((nodebug))
+#else
+#define NODEBUG
+#endif
+
+// Const global variable. Use it so it gets emitted.
+NODEBUG static const int const_global_int_def = 1;
+void func1(int);
+void func2() { func1(const_global_int_def); }
+// YESINFO-DAG: !DIGlobalVariable(name: "const_global_int_def"
+// NOINFO-NOT: !DIGlobalVariable(name: "const_global_int_def"
+
+// Global variable with a more involved type.
+// If the variable has no debug info, the type should not appear either.
+struct S1 {
+ int a;
+ int b;
+};
+NODEBUG S1 global_struct = { 2, 3 };
+// YESINFO-DAG: !DICompositeType({{.*}} name: "S1"
+// NOINFO-NOT: !DICompositeType({{.*}} name: "S1"
+// YESINFO-DAG: !DIGlobalVariable(name: "global_struct"
+// NOINFO-NOT: !DIGlobalVariable(name: "global_struct"
+
+// Static data members. Const member needs a use.
+// Also the class as a whole needs a use, so that we produce debug info for
+// the entire class (iterating over the members, demonstrably skipping those
+// with 'nodebug').
+struct S2 {
+ NODEBUG static int static_member;
+ NODEBUG static const int static_const_member = 4;
+};
+int S2::static_member = 5;
+void func3() {
+ S2 junk;
+ func1(S2::static_const_member);
+}
+// YESINFO-DAG: !DIGlobalVariable(name: "static_member"
+// NOINFO-NOT: !DIGlobalVariable(name: "static_member"
+// YESINFO-DAG: !DIDerivedType({{.*}} name: "static_const_member"
+// NOINFO-NOT: !DIDerivedType({{.*}} name: "static_const_member"
+
+// Function-local static and auto variables.
+void func4() {
+ NODEBUG static int static_local = 6;
+ NODEBUG int normal_local = 7;
+}
+// YESINFO-DAG: !DIGlobalVariable(name: "static_local"
+// NOINFO-NOT: !DIGlobalVariable(name: "static_local"
+// YESINFO-DAG: !DILocalVariable(name: "normal_local"
+// NOINFO-NOT: !DILocalVariable(name: "normal_local"
diff --git a/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp b/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp
index cac16b600890..a7e02e481320 100644
--- a/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp
+++ b/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp
@@ -7,15 +7,15 @@ struct T {
void foo(int (T::*method)()) {}
-// A pointer to a member function is a pair of function- and this-pointer.
-// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type,
-// DARWIN-X64-SAME: size: 128
-// WIN32-X64-SAME: size: 64
-
struct Incomplete;
int (Incomplete::**bar)();
+// A pointer to a member function is a pair of function- and this-pointer.
// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type,
// DARWIN-X64-SAME: size: 128
// WIN32-X64-NOT: size:
// CHECK-SAME: extraData: {{.*}})
+
+// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type,
+// DARWIN-X64-SAME: size: 128
+// WIN32-X64-SAME: size: 64
diff --git a/test/CodeGenCXX/debug-info-scoped-class.cpp b/test/CodeGenCXX/debug-info-scoped-class.cpp
new file mode 100644
index 000000000000..de4aee9a1b44
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-scoped-class.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -std=c++11 \
+// RUN: -triple thumbv7-apple-ios %s -o - | FileCheck %s
+
+// This forward-declared scoped enum will be created while building its own
+// declcontext. Make sure it is only emitted once.
+
+struct A {
+ enum class Return;
+ Return f1();
+};
+A::Return* f2() {}
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Return",
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-NOT: tag: DW_TAG_enumeration_type, name: "Return"
diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp
index 8e5207d5c30b..ed8ae015cfc3 100644
--- a/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/test/CodeGenCXX/debug-info-static-member.cpp
@@ -1,4 +1,6 @@
// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck %s
// PR14471
enum X {
@@ -10,7 +12,11 @@ class C
const static bool const_a = true;
protected:
static int b;
+#if __cplusplus >= 201103L
+ constexpr static float const_b = 3.14;
+#else
const static float const_b = 3.14;
+#endif
public:
static int c;
const static int const_c = 18;
@@ -18,37 +24,35 @@ public:
static X x_a;
};
-int C::a = 4;
-int C::b = 2;
-int C::c = 1;
-
-int main()
-{
- C instance_C;
- instance_C.d = 8;
- return C::c;
-}
-
// The definition of C::a drives the emission of class C, which is
// why the definition of "a" comes before the declarations while
// "b" and "c" come after.
// 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: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct"
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var"
+// 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: !DIGlobalVariable(name: "a", {{.*}}variable: i32* @_ZN1C1aE, declaration: ![[DECL_A:[0-9]+]])
+int C::a = 4;
+// CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
// CHECK-NOT: size:
// CHECK-NOT: align:
// CHECK-NOT: offset:
// CHECK-SAME: flags: DIFlagStaticMember)
//
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C")
+//
// 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:
@@ -61,7 +65,7 @@ int main()
// 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:
@@ -78,12 +82,19 @@ int main()
// 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: !DIGlobalVariable(name: "b", {{.*}}variable: i32* @_ZN1C1bE, declaration: ![[DECL_B]])
+int C::b = 2;
+// CHECK: !DIGlobalVariable(name: "c", {{.*}}variable: i32* @_ZN1C1cE, declaration: ![[DECL_C]])
+int C::c = 1;
-// CHECK: [[NS_X:![0-9]+]] = !DINamespace(name: "x"
+int main()
+{
+ C instance_C;
+ instance_C.d = 8;
+ return C::c;
+}
+
+// CHECK-NOT: !DIGlobalVariable(name: "anon_static_decl_var"
// 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.
@@ -94,9 +105,6 @@ struct anon_static_decl_struct {
}
-// 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;
}
@@ -113,12 +121,6 @@ int static_decl_templ_ref() {
return static_decl_templ<int>::static_decl_templ_var;
}
-// 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: !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
// declaration, not the definition. Also, since we look at the canonical
@@ -135,10 +137,10 @@ const int V::const_va;
namespace x {
struct y {
+// CHECK: !DIGlobalVariable(name: "z",
+// CHECK-SAME: scope: [[NS_X:![0-9]+]]
+// CHECK: [[NS_X]] = !DINamespace(name: "x"
static int z;
};
int y::z;
}
-
-// 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 04c63ae2ff24..08146c25263b 100644
--- a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
+++ b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
@@ -6,6 +6,11 @@
// LINES-ONLY-NOT: !DICompositeType(tag: DW_TAG_structure_type
+// "h" is at the top because it's in the compile unit's retainedTypes: list.
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "h<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
template <typename T>
struct a {
};
@@ -85,9 +90,6 @@ template <typename T>
struct h {
};
template class h<int>;
-// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "h<int>"
-// CHECK-NOT: DIFlagFwdDecl
-// CHECK-SAME: ){{$}}
template <typename T>
struct i {
diff --git a/test/CodeGenCXX/debug-info-template-limit.cpp b/test/CodeGenCXX/debug-info-template-limit.cpp
index 5c4ac0cc3e15..172ab94dce62 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 -debug-info-kind=limited -triple %itanium_abi_triple %s -o - | FileCheck %s
// Check that this pointer type is TC<int>
-// CHECK: ![[LINE:[0-9]+]] = !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
-// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS2TCIiE"
+// CHECK: ![[LINE:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
+// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[LINE]]
template<typename T>
class TC {
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index b94ff05df44e..88f024b59abf 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -16,6 +16,12 @@ 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
}
+// The compile unit pulls in the global variables first.
+// CHECK: !DIGlobalVariable(name: "x",
+// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
+// CHECK-SAME: variable: %"struct.outer<foo>::inner"* @x
+
+// CHECK: ![[OUTER_FOO_INNER_ID:[0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier:
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
// CHECK-SAME: elements: [[FOO_MEM:![0-9]*]]
// CHECK-SAME: identifier: "_ZTS3foo"
@@ -23,42 +29,35 @@ inline int add3(int x) {
// 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]*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier: "[[OUTER_FOO_INNER_ID]]")
-
-// 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]] = !DITemplateTypeParameter(name: "T", type: !"_ZTS4elem")
+// CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, ![[OUTER_FOO_INNER_ID]]}
-// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
-// CHECK-SAME: vtableHolder: !"_ZTS7MyClass"
+// CHECK-SAME: vtableHolder: [[C]]
// CHECK-SAME: identifier: "_ZTS7MyClass")
// CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_FUNC:![0-9]*]]}
// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$MyClass"
// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 7,
-// CHECK: [[ELEM:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "elem"
+// CHECK: !DISubprogram(name: "add<2>"
+// CHECK-SAME: scope: [[C]]
+//
+// CHECK: [[VIRT_TEMP:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "virt<elem>"
+// CHECK-SAME: elements: [[VIRT_MEM:![0-9]*]]
+// CHECK-SAME: vtableHolder: [[VIRT_TEMP]]
+// CHECK-SAME: templateParams: [[VIRT_TEMP_PARAM:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTS4virtI4elemE"
+
+// CHECK: [[ELEM:![0-9]+]] = distinct !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]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !"_ZTS4elem"
-// CHECK-SAME: baseType: !"_ZTS4virtI4elemE"
+// CHECK: [[ELEM_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: [[ELEM]]
+// CHECK-SAME: baseType: [[VIRT_TEMP:![0-9]+]]
-// 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: !DISubprogram(name: "MyClass"
-// CHECK-SAME: scope: !"_ZTS7MyClass"
-// CHECK: !DISubprogram(name: "add<2>"
-// CHECK-SAME: scope: !"_ZTS7MyClass"
+// CHECK: [[VIRT_TEMP_PARAM]] = !{[[VIRT_T:![0-9]*]]}
+// CHECK: [[VIRT_T]] = !DITemplateTypeParameter(name: "T", type: [[ELEM]])
template<typename T>
struct outer {
@@ -80,10 +79,6 @@ inline void func() {
outer<foo>::inner 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 {
T* values;
@@ -98,3 +93,11 @@ inline void f1() {
void f2() {
virt<elem> d; // emit 'virt<elem>'
}
+
+// 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: !DISubprogram(name: "MyClass"
+// CHECK-SAME: scope: [[C]]
diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp
index 1e8bdb1ad714..7a0d0d4a2755 100644
--- a/test/CodeGenCXX/debug-info-template-quals.cpp
+++ b/test/CodeGenCXX/debug-info-template-quals.cpp
@@ -15,17 +15,17 @@ void foo (const char *c) {
str.assign(c, str);
}
-// CHECK: [[BS:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>"
+// CHECK: [[P:![0-9]*]] = !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: [[BS:.*]] = distinct !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]] = !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: [[ARGS]] = !{!{{.*}}, !{{.*}}, [[P]], [[R:.*]]}
// CHECK: [[R]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[CON2:![0-9]*]]
-// CHECK: [[CON2]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: !"_ZTS12basic_stringIcE"
+// CHECK: [[CON2]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[BS]]
// 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 74adef9a5f7a..d35bb70fa713 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -1,73 +1,105 @@
// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s
// CHECK: !DICompileUnit(
-// CHECK-SAME: retainedTypes: [[RETAIN:![0-9]*]]
// CHECK: [[EMPTY:![0-9]*]] = !{}
-// CHECK: [[RETAIN]] = !{!{{[0-9]]*}}, [[FOO:![0-9]*]],
+struct foo {
+ char pad[8]; // make the member pointer to 'e' a bit more interesting (nonzero)
+ int e;
+ void f();
+ static void g();
+};
+
+typedef int foo::*foo_mem;
+
+template<typename T, T, const int *x, foo_mem a, void (foo::*b)(), void (*f)(), int ...Is>
+struct TC {
+ struct nested {
+ };
+};
+
+// CHECK: [[INT:![0-9]+]] = !DIBasicType(name: "int"
+int glb;
+void func();
+
+// CHECK: !DIGlobalVariable(name: "tci",
+// CHECK-SAME: type: ![[TCNESTED:[0-9]+]]
+// CHECK-SAME: variable: %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested"* @tci
+// CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
+// CHECK-SAME: scope: ![[TC:[0-9]+]],
-// 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: ![[TC]] = distinct !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]*]]
+TC
// CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]}
-//
// CHECK: [[TCARG1]] = !DITemplateTypeParameter(name: "T", type: [[UINT:![0-9]*]])
// CHECK: [[UINT:![0-9]*]] = !DIBasicType(name: "unsigned int"
+< unsigned,
// CHECK: [[TCARG2]] = !DITemplateValueParameter(type: [[UINT]], value: i32 2)
+ 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: [[CINT]] = !DIDerivedType(tag: DW_TAG_const_type, {{.*}}baseType: [[INT]]
+ &glb,
// 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")
+// CHECK: [[MEMINTPTR]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, {{.*}}baseType: [[INT]], {{.*}}extraData: ![[FOO:[0-9]+]])
+//
+// 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]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
+// CHECK: !DISubprogram(name: "f", linkageName: "_ZN3foo1fEv", {{.*}}type: [[FTYPE:![0-9]*]]
//
// 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]] = !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: [[FTYPE:![0-9]*]] = !DISubroutineType(types: [[FARGS:![0-9]*]])
// CHECK: [[FARGS]] = !{null, [[FARG1:![0-9]*]]}
// CHECK: [[FARG1]] = !DIDerivedType(tag: DW_TAG_pointer_type,
-// CHECK-SAME: baseType: !"_ZTS3foo"
+// CHECK-SAME: baseType: ![[FOO]]
// CHECK-NOT: line:
// CHECK-SAME: size: 64, align: 64
// CHECK-NOT: offset: 0
// CHECK-SAME: DIFlagArtificial
-//
-// 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: [[FUNTYPE:![0-9]*]] = !DISubroutineType(types: [[FUNARGS:![0-9]*]])
// CHECK: [[FUNARGS]] = !{null}
+ &foo::e,
+// 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]], {{.*}}extraData: ![[FOO]])
+ &foo::f,
+// CHECK: [[TCARG6]] = !DITemplateValueParameter(name: "f", type: [[FUNPTR:![0-9]*]], value: void ()* @_ZN3foo1gEv)
+// CHECK: [[FUNPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[FUNTYPE]]
+ &foo::g,
// 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]] = !DITemplateValueParameter(type: [[INT]], value: i32 1)
+ 1,
// CHECK: [[TCARG7_2]] = !DITemplateValueParameter(type: [[INT]], value: i32 2)
+ 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]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
-// CHECK: !DISubprogram(name: "f", linkageName: "_ZN3foo1fEv", {{.*}}type: [[FTYPE:![0-9]*]]
-//
+ 3>::nested tci;
-// 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: !DIGlobalVariable(name: "tcn"
+// CHECK-SAME: type: ![[TCNT:[0-9]+]]
+// CHECK-SAME: variable: %struct.TC* @tcn
+TC
+// CHECK: ![[TCNT]] ={{.*}}!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]] = !DITemplateTypeParameter(name: "T", type: [[INT]])
+<int,
// CHECK: [[TCNARG2]] = !DITemplateValueParameter(type: [[INT]], value: i32 -3)
+ -3,
// CHECK: [[TCNARG3]] = !DITemplateValueParameter(name: "x", type: [[CINTPTR]], value: i8 0)
+ nullptr,
// 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]] = !DITemplateValueParameter(name: "a", type: [[MEMINTPTR]], value: i64 -1)
+ nullptr,
//
// 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
@@ -75,69 +107,38 @@
// member function pointers. For now, it's simpler just to emit the 'i8 0'.
//
// CHECK: [[TCNARG5]] = !DITemplateValueParameter(name: "b", type: [[MEMFUNPTR]], value: i8 0)
+ nullptr,
// CHECK: [[TCNARG6]] = !DITemplateValueParameter(name: "f", type: [[FUNPTR]], value: i8 0)
+ nullptr
// CHECK: [[TCNARG7]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "Is", value: [[EMPTY]])
+ > tcn;
+
+template<typename>
+struct tmpl_impl {
+};
+
+template <template <typename> class tmpl, int &lvr, int &&rvr>
+struct NN {
+};
+
+// CHECK: !DIGlobalVariable(name: "nn"
+// CHECK-SAME: type: ![[NNT:[0-9]+]]
+// CHECK-SAME: variable: %struct.NN* @nn
// FIXME: these parameters should probably be rendered as 'glb' rather than
// '&glb', since they're references, not pointers.
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "NN<tmpl_impl, &glb, &glb>",
+// CHECK: ![[NNT]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "NN<tmpl_impl, &glb, &glb>",
// CHECK-SAME: templateParams: [[NNARGS:![0-9]*]]
-// CHECK-SAME: identifier: "[[NNT:.*]]")
+// CHECK-SAME: identifier:
// CHECK: [[NNARGS]] = !{[[NNARG1:![0-9]*]], [[NNARG2:![0-9]*]], [[NNARG3:![0-9]*]]}
// 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]] = !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: !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: !DIGlobalVariable(name: "tcn"
-// CHECK-SAME: type: !"[[TCNT]]"
-// CHECK-SAME: variable: %struct.TC* @tcn
-
-// 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;
- void f();
- static void g();
-};
-
-typedef int foo::*foo_mem;
-
-template<typename T, T, const int *x, foo_mem a, void (foo::*b)(), void (*f)(), int ...Is>
-struct TC {
- struct nested {
- };
-};
-
-int glb;
-void func();
-
-TC<unsigned, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested tci;
-TC<int, -3, nullptr, nullptr, nullptr, nullptr> tcn;
-
-template<typename>
-struct tmpl_impl {
-};
-
-template <template <typename> class tmpl, int &lvr, int &&rvr>
-struct NN {
-};
-
NN<tmpl_impl, glb, glb> nn;
+// CHECK: ![[PADDINGATEND:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PaddingAtEnd",
struct PaddingAtEnd {
int i;
char c;
@@ -145,6 +146,11 @@ struct PaddingAtEnd {
PaddingAtEnd PaddedObj = {};
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PaddingAtEndTemplate<&PaddedObj>"
+// CHECK-SAME: templateParams: [[PTOARGS:![0-9]*]]
+// CHECK: [[PTOARGS]] = !{[[PTOARG1:![0-9]*]]}
+// CHECK: [[PTOARG1]] = !DITemplateValueParameter(type: [[CONST_PADDINGATEND_PTR:![0-9]*]], value: %struct.PaddingAtEnd* @PaddedObj)
+// CHECK: [[CONST_PADDINGATEND_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[PADDINGATEND]], size: 64, align: 64)
template <PaddingAtEnd *>
struct PaddingAtEndTemplate {
};
diff --git a/test/CodeGenCXX/debug-info-varargs.cpp b/test/CodeGenCXX/debug-info-varargs.cpp
index 52bffe6c9285..7afbcd255842 100644
--- a/test/CodeGenCXX/debug-info-varargs.cpp
+++ b/test/CodeGenCXX/debug-info-varargs.cpp
@@ -2,13 +2,7 @@
struct A
{
- // CHECK: !DISubprogram(name: "a", linkageName: "_ZN1A1aEiz"
- // CHECK-SAME: line: [[@LINE+2]]
- // CHECK-SAME: type: ![[ATY:[0-9]+]]
void a(int c, ...) {}
- // 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: !DISubprogram(name: "b", linkageName: "_Z1biz"
@@ -18,6 +12,14 @@ void b(int c, ...) {
// CHECK: ![[BTY]] = !DISubroutineType(types: ![[BARGS:[0-9]+]])
// CHECK: ![[BARGS]] = !{null, !{{[0-9]+}}, null}
+ // The subprogram "a" comes after "b" because the function comes later.
+ // CHECK: !DISubprogram(name: "a", linkageName: "_ZN1A1aEiz"
+ // CHECK-SAME: line: 5,
+ // CHECK-SAME: type: ![[ATY:[0-9]+]]
+ // 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}
+
A a;
// CHECK: !DILocalVariable(name: "fptr"
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 29ed9e93156d..2e8d5fd5f137 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -1,5 +1,24 @@
-// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
-// RUN: %clang_cc1 -triple i686-pc-windows-msvc -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=BOTH
+// RUN: %clang_cc1 -triple i686-pc-windows-msvc -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=MSVC --check-prefix=BOTH
+
+// CHECK: define void @_ZN7pr147634funcENS_3fooE
+// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata ![[EXPR:[0-9]+]])
+
+// !llvm.dbg.cu pulls in globals and their types first.
+// CHECK-NOT: !DIGlobalVariable(name: "c"
+// 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: ![[INCTYPE:[0-9]+]]
+
+// CHECK: ![[INCTYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete"
+// CHECK-SAME: DIFlagFwdDecl
template<typename T> struct Identity {
typedef T Type;
@@ -47,38 +66,27 @@ namespace VirtualDtor {
namespace VirtualBase {
struct A { int a; };
struct B : virtual A { int b; };
+// BOTH: ![[VBASE_B:[0-9]+]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "B",{{.*}} line: [[@LINE-1]],
+// MSVC-SAME: size: 96, align: 32
+// CHECK-SAME: size: 128, align: 64,
+// BOTH-NOT: offset:
+// BOTH-NOT: DIFlagFwdDecl
+// BOTH-SAME: elements: [[VBASE_B_DEF:![0-9]+]]
+// BOTH: [[VBASE_B_DEF]] = !{[[VBASE_A_IN_B:![0-9]+]],
+//
+// Look for the vbtable offset of A, which should be 4 for MSVC, 24 otherwise.
+// BOTH: [[VBASE_A_IN_B]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[VBASE_B]],
+// BOTH-SAME: baseType: ![[VBASE_A:[0-9]+]],
+// MSVC-SAME: offset: 4,
+// CHECK-SAME: offset: 24,
+//
+// BOTH: ![[VBASE_A]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "A",
void f() {
B b;
}
}
-// 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]] = !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]] = !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;
@@ -91,72 +99,56 @@ class Cls {
Cls obj;
}
+// CHECK: [[FUNC:[0-9]+]] = distinct !DISubprogram(name: "func", linkageName: "_ZN7pr147634funcENS_3fooE"
+// CHECK-SAME: type: {{![0-9]+}}
+// CHECK-SAME: isDefinition: true
+
+// CHECK: [[PR14763:![0-9]+]] = !DINamespace(name: "pr14763"
namespace pr14763 {
struct foo {
+// CHECK: ![[FOO:[0-9]+]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-SAME: scope: [[PR14763]]
+// CHECK-SAME: identifier:
foo(const foo&);
};
+// For some reason function arguments ended up down here
+// CHECK: ![[F]] = !DILocalVariable(name: "f", arg: 1, scope: ![[FUNC]]
+// CHECK-SAME: type: ![[FOO]]
+// CHECK: ![[EXPR]] = !DIExpression(DW_OP_deref)
foo func(foo f) {
return f; // reference 'f' for now because otherwise we hit another bug
}
-// 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]] = !DIDerivedType(tag: DW_TAG_member, name: "i"
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "b"
-// CHECK-SAME: DIFlagFwdDecl
-
-// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func", linkageName: "_ZN7pr147634funcENS_3fooE"
-// CHECK-SAME: type: [[FUNC_TYPE:![0-9]*]]
-// CHECK-SAME: isDefinition: true
}
void foo() {
+// CHECK: !DILocalVariable(name: "c"
+// CHECK-NOT: arg:
+// CHECK-SAME: )
const wchar_t c = L'x';
wchar_t d = c;
}
-// CHECK-NOT: !DIGlobalVariable(name: "c"
-
namespace pr9608 { // also pr9600
struct incomplete;
incomplete (*x)[3];
-// 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: ![[F]] = !DILocalVariable(name: "f", arg: 1, scope: [[FUNC]]
-// CHECK-SAME: type: !"[[FOO]]"
-// CHECK: ![[EXPR]] = !DIExpression(DW_OP_deref)
-
-// CHECK: !DILocalVariable(name: "c"
-// CHECK-NOT: arg:
-// CHECK-SAME: )
-
namespace pr16214 {
+// 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]*]]}
struct a {
+// CHECK: [[A_I]] = !DIDerivedType(tag: DW_TAG_member, name: "i"
int i;
};
typedef a at;
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "b"
+// CHECK-SAME: DIFlagFwdDecl
struct b {
};
diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp
index a022fad1b6b9..b01f770bdd97 100644
--- a/test/CodeGenCXX/debug-lambda-expressions.cpp
+++ b/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -17,23 +17,31 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// Randomness for file. -- 6
// CHECK: [[FILE:.*]] = !DIFile(filename: "{{.*}}debug-lambda-expressions.cpp",
+// CVAR:
+// CHECK: !DIGlobalVariable(name: "cvar"
+// CHECK-SAME: line: [[CVAR_LINE:[0-9]+]]
+// CHECK-SAME: type: ![[CVAR_T:[0-9]+]]
+// CHECK: ![[CVAR_T]] = distinct !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: !DIGlobalVariable(name: "var"
+// CHECK-SAME: line: [[VAR_LINE:[0-9]+]]
+// CHECK-SAME: type: ![[VAR_T:[0-9]+]]
+// CHECK: ![[VAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
+// CHECK-SAME: line: [[VAR_LINE]],
+// CHECK-SAME: elements: ![[VAR_ARGS:[0-9]+]]
+// CHECK: ![[VAR_ARGS]] = !{!{{[0-9]+}}}
+
// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
// A: 10
// CHECK: ![[A_FUNC:.*]] = distinct !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}}, isDefinition: true
-// B: 14
-// CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}}, isDefinition: true
-
-// C: 17
-// CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}}, isDefinition: true
-
-// D: 18
-// CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}}, isDefinition: true
-
-
// Back to A. -- 78
-// CHECK: ![[LAM_A:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
+// CHECK: ![[LAM_A:.*]] = distinct !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()"
@@ -41,8 +49,11 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: line: [[A_LINE]]
// CHECK-SAME: DIFlagPublic
+// B: 14
+// CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}}, isDefinition: true
+
// Back to B. -- 67
-// CHECK: ![[LAM_B:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
+// CHECK: ![[LAM_B:.*]] = distinct !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"
@@ -54,8 +65,11 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: line: [[B_LINE]]
// CHECK-SAME: DIFlagPublic
+// C: 17
+// CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}}, isDefinition: true
+
// Back to C. -- 55
-// CHECK: ![[LAM_C:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
+// CHECK: ![[LAM_C:.*]] = distinct !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"
@@ -68,8 +82,11 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: line: [[C_LINE]]
// CHECK-SAME: DIFlagPublic
+// D: 18
+// CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}}, isDefinition: true
+
// Back to D. -- 24
-// CHECK: ![[LAM_D:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
+// CHECK: ![[LAM_D:.*]] = distinct !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"
@@ -82,21 +99,3 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-SAME: scope: ![[LAM_D]]
// CHECK-SAME: line: [[D_LINE]]
// CHECK-SAME: DIFlagPublic
-
-// CVAR:
-// 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: !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 0c413449a3ec..4af3d81983b2 100644
--- a/test/CodeGenCXX/debug-lambda-this.cpp
+++ b/test/CodeGenCXX/debug-lambda-this.cpp
@@ -12,10 +12,11 @@ int D::d(int x) {
}();
}
+// CHECK: ![[D:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "D",
+// CHECK: ![[POINTER:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[D]], size: 64, align: 64)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "this",
// CHECK-SAME: line: 11
-// CHECK-SAME: baseType: ![[POINTER:[0-9]+]]
+// CHECK-SAME: baseType: ![[POINTER]]
// 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/default_calling_conv.cpp b/test/CodeGenCXX/default_calling_conv.cpp
new file mode 100644
index 000000000000..95c214a223d4
--- /dev/null
+++ b/test/CodeGenCXX/default_calling_conv.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fdefault-calling-conv=cdecl -emit-llvm -o - %s | FileCheck %s --check-prefix=CDECL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i786-unknown-linux-gnu -target-feature +sse4.2 -fdefault-calling-conv=fastcall -emit-llvm -o - %s | FileCheck %s --check-prefix=FASTCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+
+// CDECL: define void @_Z5test1v
+// FASTCALL: define x86_fastcallcc void @_Z5test1v
+// STDCALL: define x86_stdcallcc void @_Z5test1v
+// VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+void test1() {}
+
+// ALL: define void @_Z5test2v
+void __attribute__((cdecl)) test2() {}
+
+// ALL: define x86_fastcallcc void @_Z5test3v
+void __attribute__((fastcall)) test3() {}
+
+// ALL: define x86_stdcallcc void @_Z5test4v
+void __attribute__((stdcall)) test4() {}
+
+// ALL: define x86_vectorcallcc void @_Z5test5v
+void __attribute__((vectorcall)) test5() {}
+
+// ALL: define linkonce_odr void @_ZN1A11test_memberEv
+class A {
+public:
+ void test_member() {}
+};
+
+void test() {
+ A a;
+ a.test_member();
+}
diff --git a/test/CodeGenCXX/delete-two-arg.cpp b/test/CodeGenCXX/delete-two-arg.cpp
index 85275b3eb176..68a6fa6736eb 100644
--- a/test/CodeGenCXX/delete-two-arg.cpp
+++ b/test/CodeGenCXX/delete-two-arg.cpp
@@ -27,7 +27,7 @@ namespace test2 {
// CHECK: define [[A:%.*]]* @_ZN5test24testEv()
A *test() {
- // CHECK: [[NEW:%.*]] = call noalias i8* @_Znaj(i32 44)
+ // CHECK: [[NEW:%.*]] = call 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, i8* [[NEW]], i32 4
@@ -63,7 +63,7 @@ namespace test3 {
// CHECK-LABEL: define void @_ZN5test34testEv()
void test() {
- // CHECK: call noalias i8* @_Znaj(i32 24)
+ // CHECK: call i8* @_Znaj(i32 24)
// CHECK-NEXT: bitcast
// CHECK-NEXT: store i32 5
(void) new B[5];
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 529603142d31..d6aabee58b9e 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -4,6 +4,9 @@
// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns -std=c++11 > %t2
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s
+// REQUIRES: asserts
struct A {
int a;
@@ -428,3 +431,64 @@ namespace test10 {
return true;
}
}
+
+#if __cplusplus >= 201103L
+namespace test11 {
+
+// Check that lifetime.end is emitted in the landing pad.
+
+// CHECK6-LABEL: define void @_ZN6test1115testLifetimeEndEi(
+// CHECK6: entry:
+// CHECK6: [[T1:%[a-z0-9]+]] = alloca %"struct.test11::S1"
+// CHECK6: [[T2:%[a-z0-9]+]] = alloca %"struct.test11::S1"
+// CHECK6: [[T3:%[a-z0-9]+]] = alloca %"struct.test11::S1"
+
+// CHECK6: {{^}}invoke.cont
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T1]])
+// CHECK6: [[BC1:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T1]] to i8*
+// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC1]])
+// CHECK6: {{^}}lpad
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T1]])
+// CHECK6: [[BC2:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T1]] to i8*
+// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC2]])
+
+// CHECK6: {{^}}invoke.cont
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T2]])
+// CHECK6: [[BC3:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T2]] to i8*
+// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC3]])
+// CHECK6: {{^}}lpad
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T2]])
+// CHECK6: [[BC4:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T2]] to i8*
+// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC4]])
+
+// CHECK6: {{^}}invoke.cont
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T3]])
+// CHECK6: [[BC5:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T3]] to i8*
+// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC5]])
+// CHECK6: {{^}}lpad
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T3]])
+// CHECK6: [[BC6:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T3]] to i8*
+// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC6]])
+
+ struct S1 {
+ ~S1();
+ int a[8];
+ };
+
+ void func1(S1 &) noexcept(false);
+
+ void testLifetimeEnd(int n) {
+ if (n < 10) {
+ S1 t1;
+ func1(t1);
+ } else if (n < 100) {
+ S1 t2;
+ func1(t2);
+ } else if (n < 1000) {
+ S1 t3;
+ func1(t3);
+ }
+ }
+
+}
+#endif
diff --git a/test/CodeGenCXX/discard-name-values.cpp b/test/CodeGenCXX/discard-name-values.cpp
new file mode 100644
index 000000000000..49cb7d2fc058
--- /dev/null
+++ b/test/CodeGenCXX/discard-name-values.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -triple=armv7-apple-darwin -emit-llvm -std=c++11 %s -o - -O1 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple=armv7-apple-darwin -emit-llvm -std=c++11 %s -o - -O1 -discard-value-names | FileCheck %s --check-prefix=DISCARDVALUE
+
+int foo(int bar) {
+ return bar;
+}
+
+// CHECK: ret i32 %bar
+// DISCARDVALUE: ret i32 %0
+
diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp
index 76f692dbd301..1c56251328d6 100644
--- a/test/CodeGenCXX/dllexport-members.cpp
+++ b/test/CodeGenCXX/dllexport-members.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -fms-compatibility-version=18 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fms-compatibility-version=18 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -fms-compatibility-version=19 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=M32VS2015 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fms-compatibility-version=19 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=M64VS2015 %s
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
@@ -427,6 +429,32 @@ __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDe
ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
+// Export defaulted member function definitions declared inside class.
+struct ExportDefaultedInclassDefs {
+ __declspec(dllexport) ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2013-DAG: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2015-NOT: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+
+ __declspec(dllexport) ~ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2013-DAG: define weak_odr dllexport void @"\01??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2015-NOT: define weak_odr dllexport void @"\01??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+
+ __declspec(dllexport) ExportDefaultedInclassDefs(const ExportDefaultedInclassDefs&) = default;
+ // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2013-DAG: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2015-NOT: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+
+ __declspec(dllexport) ExportDefaultedInclassDefs& operator=(const ExportDefaultedInclassDefs&) = default;
+ // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"\01??4ExportDefaultedInclassDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define weak_odr dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"\01??4ExportDefaultedInclassDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+};
+
+
// Export allocation functions.
struct ExportAlloc {
__declspec(dllexport) void* operator new(__SIZE_TYPE__);
diff --git a/test/CodeGenCXX/dllexport-ms-friend.cpp b/test/CodeGenCXX/dllexport-ms-friend.cpp
new file mode 100644
index 000000000000..7bcf5905e5e5
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-ms-friend.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -emit-llvm -O0 -o - %s | FileCheck %s
+
+// Friend functions defined in classes are emitted.
+// CHECK: define weak_odr dllexport void @"\01?friend1@@YAXXZ"()
+struct FuncFriend1 {
+ friend __declspec(dllexport) void friend1() {}
+};
+
+// But function templates and functions defined in class templates are not
+// emitted.
+// CHECK-NOT: friend2
+// CHECK-NOT: friend3
+// CHECK-NOT: friend4
+struct FuncFriend2 {
+ template<typename> friend __declspec(dllexport) void friend2() {}
+};
+template<typename> struct FuncFriend3 {
+ friend __declspec(dllexport) void friend3() {}
+ struct Inner {
+ friend __declspec(dllexport) void friend4() {}
+ };
+};
diff --git a/test/CodeGenCXX/dllexport-pr26549.cpp b/test/CodeGenCXX/dllexport-pr26549.cpp
new file mode 100644
index 000000000000..ceb2e0685ef1
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-pr26549.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc -emit-llvm -o - | FileCheck %s
+
+template <typename> struct MessageT { };
+extern template struct MessageT<int>;
+
+// CHECK: define weak_odr dllexport {{.*}} %struct.MessageT* @"\01??4?$MessageT@H@@QEAAAEAU0@AEBU0@@Z"(
+template struct __declspec(dllexport) MessageT<int>;
+// Previously we crashed when this dllexport was the last thing in the file.
+// DO NOT ADD MORE TESTS AFTER THIS LINE!
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index 1412ad866bd3..7cef7c2d127e 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -1,5 +1,9 @@
-// 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-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 -check-prefix=M32MSVC2015 %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 -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 -check-prefix=M32MSVC2013 %s
+
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2015 -check-prefix=M64MSVC2015 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2013 -check-prefix=M64MSVC2013 %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
@@ -486,7 +490,7 @@ struct S {
struct CtorWithClosure {
__declspec(dllexport) CtorWithClosure(...) {}
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) comdat
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
// 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]]
@@ -503,7 +507,7 @@ struct CtorWithClosure {
struct __declspec(dllexport) ClassWithClosure {
DELETE_IMPLICIT_MEMBERS(ClassWithClosure);
ClassWithClosure(...) {}
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) comdat
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
// 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]]
@@ -520,17 +524,19 @@ struct __declspec(dllexport) NestedOuter {
};
};
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) comdat
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) comdat
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
template <typename T>
struct SomeTemplate {
SomeTemplate(T o = T()) : o(o) {}
T o;
};
+// MSVC2015-DAG: define weak_odr dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}@$$Q{{.+}}@@Z"
+// MSVC2013-DAG: define weak_odr dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z"
struct __declspec(dllexport) InheritFromTemplate : SomeTemplate<int> {};
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) comdat
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
namespace PR23801 {
template <typename>
@@ -547,7 +553,7 @@ struct __declspec(dllexport) B {
}
//
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ"({{.*}}) comdat
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
struct __declspec(dllexport) T {
// Copy assignment operator:
@@ -555,7 +561,7 @@ struct __declspec(dllexport) T {
// Explicitly defaulted copy constructur:
T(const T&) = default;
- // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
+ // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
void a() {}
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
@@ -570,6 +576,30 @@ struct __declspec(dllexport) T {
USEVAR(T::b)
int T::c;
+// Export template class with static member variable
+// MSC-DAG: @"\01?StaticClassVarExpTmplClass@?$TmplClass@H@@2HA" = weak_odr dllexport global i32 0, comdat, align 4
+// GNU-DAG: @_ZN9TmplClassIiE26StaticClassVarExpTmplClassE = weak_odr dllexport global i32 0, comdat, align 4
+template<typename T>
+struct __declspec(dllexport) TmplClass
+{
+ static T StaticClassVarExpTmplClass;
+};
+
+template<typename T>
+T TmplClass<T>::StaticClassVarExpTmplClass;
+
+// Export a definition of a template function.
+// MSC-DAG: define weak_odr dllexport i32 @"\01??$TypeFunTmpl@H@@YAHH@Z"
+// GNU-DAG: define weak_odr dllexport i32 @_Z11TypeFunTmplIiET_S0_
+template<typename T>
+T __declspec(dllexport) TypeFunTmpl(T t) { return t + t; }
+
+// Instantiate the exported template class and the exported template function.
+int useExportedTmplStaticAndFun()
+{
+ return TmplClass<int>::StaticClassVarExpTmplClass + TypeFunTmpl<int>(10);
+}
+
template <typename T> struct __declspec(dllexport) U { void foo() {} };
struct __declspec(dllexport) V : public U<int> { };
// U<int>'s assignment operator is emitted.
@@ -592,7 +622,8 @@ struct __declspec(dllexport) X : public virtual W {};
struct __declspec(dllexport) Y {
// Move assignment operator:
- // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
+ // MSVC2015-DAG: define weak_odr dllexport {{.+}} @"\01??4Y@@Q{{.+}}@$$Q{{.+}}@@Z"
+ // MSVC2013-DAG: define weak_odr dllexport {{.+}} @"\01??4Y@@Q{{.+}}0@A{{.+}}0@@Z"
int x;
};
@@ -616,9 +647,34 @@ namespace UseDtorAlias {
struct __declspec(dllexport) DefaultedCtorsDtors {
DefaultedCtorsDtors() = default;
- // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
+ // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
~DefaultedCtorsDtors() = default;
- // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
+ // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
+};
+
+// Export defaulted member function definitions declared inside class.
+struct __declspec(dllexport) ExportDefaultedInclassDefs {
+ ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2013-DAG: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2015-NOT: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+
+ ~ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2013-DAG: define weak_odr dllexport void @"\01??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2015-NOT: define weak_odr dllexport void @"\01??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+
+ ExportDefaultedInclassDefs(const ExportDefaultedInclassDefs&) = default;
+ // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2013-DAG: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2015-NOT: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+
+ ExportDefaultedInclassDefs& operator=(const ExportDefaultedInclassDefs&) = default;
+ // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"\01??4ExportDefaultedInclassDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define weak_odr dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"\01??4ExportDefaultedInclassDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
};
namespace ReferencedInlineMethodInNestedClass {
@@ -690,7 +746,7 @@ template <typename T> struct ExplicitInstConstexprMembers {
// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@XZ"
ExplicitInstConstexprMembers(const ExplicitInstConstexprMembers&) = default;
- // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z"
+ // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z"
constexpr int f() const { return 42; }
// M32-DAG: define weak_odr dllexport x86_thiscallcc i32 @"\01?f@?$ExplicitInstConstexprMembers@X@@QBEHXZ"
@@ -777,6 +833,22 @@ struct __declspec(dllexport) Baz {
// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %"struct.InClassInits::Baz"* @"\01??4Baz@InClassInits@@QAEAAU01@ABU01@@Z"
}
+// We had an issue where instantiating A would force emission of B's delayed
+// exported methods.
+namespace pr26490 {
+template <typename T> struct A { };
+struct __declspec(dllexport) B {
+ B(int = 0) {}
+ A<int> m_fn1() {}
+};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ"
+}
+
+// dllexport trumps dllexport on an explicit instantiation.
+template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
+template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
+
//===----------------------------------------------------------------------===//
// Classes with template base classes
@@ -891,10 +963,26 @@ template struct ExplicitInstantiationDeclTemplateBase<int>;
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
// G32-DAG: define weak_odr x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
-template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
-extern template struct ExplicitInstantiationDeclTemplateBase2<int>;
-struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {};
-template struct __declspec(dllimport) ExplicitInstantiationDeclTemplateBase2<int>;
-USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
-// G32-DAG: define weak_odr x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
+// PR26076
+struct LayerSelectionBound;
+template <typename> struct Selection {};
+typedef Selection<LayerSelectionBound> LayerSelection;
+struct LayerImpl;
+struct __declspec(dllexport) LayerTreeImpl {
+ struct __declspec(dllexport) ElementLayers {
+ LayerImpl *main = nullptr;
+ };
+ LayerSelection foo;
+};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.LayerTreeImpl::ElementLayers"* @"\01??0ElementLayers@LayerTreeImpl@@QAE@XZ"
+// M64-DAG: define weak_odr dllexport %"struct.LayerTreeImpl::ElementLayers"* @"\01??0ElementLayers@LayerTreeImpl@@QEAA@XZ"
+
+class __declspec(dllexport) ACE_Shared_Object {
+public:
+ virtual ~ACE_Shared_Object();
+};
+class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {};
+// Implicit move constructor declaration.
+// MSVC2015-DAG: define weak_odr dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
+// The declarations should not be exported.
+// MSVC2013-NOT: define weak_odr dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index e88b7e97c3e7..1fed1bf0acf1 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -63,8 +63,8 @@ struct ForceNonTrivial {
struct ImportMembers {
struct Nested;
- // M32-DAG: define x86_thiscallcc void @"\01?normalDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers* %this)
- // M64-DAG: define void @"\01?normalDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers* %this)
+ // M32-DAG: define dllexport x86_thiscallcc void @"\01?normalDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers* %this)
+ // M64-DAG: define dllexport void @"\01?normalDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers* %this)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
// M64-DAG: declare dllimport void @"\01?normalDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
@@ -95,8 +95,8 @@ struct ImportMembers {
__declspec(dllimport) void normalInlineDef();
__declspec(dllimport) inline void normalInlineDecl();
- // M32-DAG: define x86_thiscallcc void @"\01?virtualDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers* %this)
- // M64-DAG: define void @"\01?virtualDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers* %this)
+ // M32-DAG: define dllexport x86_thiscallcc void @"\01?virtualDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers* %this)
+ // M64-DAG: define dllexport void @"\01?virtualDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers* %this)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
// M64-DAG: declare dllimport void @"\01?virtualDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
@@ -127,7 +127,7 @@ struct ImportMembers {
__declspec(dllimport) virtual void virtualInlineDef();
__declspec(dllimport) virtual inline void virtualInlineDecl();
- // MSC-DAG: define void @"\01?staticDef@ImportMembers@@SAXXZ"()
+ // MSC-DAG: define dllexport void @"\01?staticDef@ImportMembers@@SAXXZ"()
// MSC-DAG: declare dllimport void @"\01?staticDecl@ImportMembers@@SAXXZ"()
// MSC-DAG: declare dllimport void @"\01?staticInclass@ImportMembers@@SAXXZ"()
// MSC-DAG: declare dllimport void @"\01?staticInlineDef@ImportMembers@@SAXXZ"()
@@ -235,8 +235,8 @@ USEMV(ImportMembers, ConstexprField)
// Import individual members of a nested class.
struct ImportMembers::Nested {
- // M32-DAG: define x86_thiscallcc void @"\01?normalDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"* %this)
- // M64-DAG: define void @"\01?normalDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M32-DAG: define dllexport x86_thiscallcc void @"\01?normalDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M64-DAG: define dllexport void @"\01?normalDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
// M64-DAG: declare dllimport void @"\01?normalDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
@@ -267,8 +267,8 @@ struct ImportMembers::Nested {
__declspec(dllimport) void normalInlineDef();
__declspec(dllimport) inline void normalInlineDecl();
- // M32-DAG: define x86_thiscallcc void @"\01?virtualDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"* %this)
- // M64-DAG: define void @"\01?virtualDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M32-DAG: define dllexport x86_thiscallcc void @"\01?virtualDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M64-DAG: define dllexport void @"\01?virtualDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
// M64-DAG: declare dllimport void @"\01?virtualDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
@@ -300,7 +300,7 @@ struct ImportMembers::Nested {
__declspec(dllimport) virtual void virtualInlineDef();
__declspec(dllimport) virtual inline void virtualInlineDecl();
- // MSC-DAG: define void @"\01?staticDef@Nested@ImportMembers@@SAXXZ"()
+ // MSC-DAG: define dllexport void @"\01?staticDef@Nested@ImportMembers@@SAXXZ"()
// MSC-DAG: declare dllimport void @"\01?staticDecl@Nested@ImportMembers@@SAXXZ"()
// MSC-DAG: declare dllimport void @"\01?staticInclass@Nested@ImportMembers@@SAXXZ"()
// MSC-DAG: declare dllimport void @"\01?staticInlineDef@Nested@ImportMembers@@SAXXZ"()
@@ -595,16 +595,16 @@ inline ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = de
// G64-DAG: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
-// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
-// M64-DAG: define %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M32-DAG: define dllexport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dllexport %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
// G64-DAG: define void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
// G64-DAG: define void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // dllimport ignored
-// M32-DAG: define x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
-// M64-DAG: define dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dllexport dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
// G32-DAG: define x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
// G64-DAG: define dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // dllimport ignored
diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp
index 071ce278a5bb..4baee50fcff3 100644
--- a/test/CodeGenCXX/dllimport-rtti.cpp
+++ b/test/CodeGenCXX/dllimport-rtti.cpp
@@ -4,7 +4,8 @@
struct __declspec(dllimport) S {
virtual void f() {}
} s;
-// MSVC-DAG: @"\01??_7S@@6B@" = available_externally dllimport
+// MSVC: [[VF_S:.*]] = private unnamed_addr constant [2 x i8*]
+// MSVC-DAG: @"\01??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VF_S]], i32 0, i32 1)
// MSVC-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
// MSVC-DAG: @"\01??_R1A@?0A@EA@S@@8" = linkonce_odr
// MSVC-DAG: @"\01??_R2S@@8" = linkonce_odr
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index b9c850b8b87b..aff240f28769 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -27,6 +27,7 @@ struct ExplicitSpec_NotImported {};
#define USEVAR(var) USEVARTYPE(int, var)
#define USE(func) void UNIQ(use)() { func(); }
#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+#define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; }
#define USECLASS(class) void UNIQ(USE)() { class x; }
#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
@@ -263,7 +264,7 @@ __declspec(dllimport) void redecl2();
void redecl2();
USE(redecl2)
-// MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
+// MSC-DAG: define dllexport void @"\01?redecl3@@YAXXZ"()
// GNU-DAG: define void @_Z7redecl3v()
__declspec(dllimport) void redecl3();
void redecl3() {} // dllimport ignored
@@ -275,7 +276,7 @@ USE(redecl3)
// GNU-DAG: declare dllimport void @_Z7friend1v()
// MSC-DAG: declare void @"\01?friend2@@YAXXZ"()
// GNU-DAG: declare void @_Z7friend2v()
-// MSC-DAG: define void @"\01?friend3@@YAXXZ"()
+// MSC-DAG: define dllexport void @"\01?friend3@@YAXXZ"()
// GNU-DAG: define void @_Z7friend3v()
// MSC-DAG: declare void @"\01?friend4@@YAXXZ"()
// GNU-DAG: declare void @_Z7friend4v()
@@ -590,6 +591,10 @@ struct __declspec(dllimport) T {
void a() {}
// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
+ static void StaticMethod();
+ // MSC-DAG: declare dllimport void @"\01?StaticMethod@T@@SAXXZ"()
+ // GNU-DAG: declare dllimport void @_ZN1T12StaticMethodEv()
+
static int b;
// MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
@@ -602,6 +607,7 @@ struct __declspec(dllimport) T {
// M19-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
};
USEMEMFUNC(T, a)
+USESTATICMEMFUNC(T, StaticMethod)
USEVAR(T::b)
USECOPYASSIGN(T)
USEMOVEASSIGN(T)
@@ -614,7 +620,7 @@ USEMEMFUNC(V, foo)
struct __declspec(dllimport) W { virtual void foo() {} };
USECLASS(W)
// vftable:
-// MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
+// MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
struct __declspec(dllimport) KeyFuncClass {
@@ -650,7 +656,7 @@ namespace DontUseDtorAlias {
namespace Vtordisp {
// Don't dllimport the vtordisp.
- // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
+ // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
class Base {
virtual void f() {}
@@ -661,7 +667,7 @@ namespace Vtordisp {
C() {}
virtual void f() {}
};
- template class C<char>;
+ USECLASS(C<int>);
}
namespace ClassTemplateStaticDef {
@@ -670,7 +676,7 @@ namespace ClassTemplateStaticDef {
static int x;
};
template <typename T> int S<T>::x;
- // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
+ // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = external dllimport global i32
int f() { return S<int>::x; }
// Partial class template specialization static field:
@@ -679,7 +685,7 @@ namespace ClassTemplateStaticDef {
static int x;
};
template <typename A> int T<A*>::x;
- // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
+ // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = external dllimport global i32
int g() { return T<void*>::x; }
}
@@ -692,26 +698,31 @@ namespace PR19933 {
template <typename T> struct A { static NonPOD x; };
template <typename T> NonPOD A<T>::x;
template struct __declspec(dllimport) A<int>;
- // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
+ USEVARTYPE(NonPOD, A<int>::x);
+ // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = external dllimport global %"struct.PR19933::NonPOD"
int f();
template <typename T> struct B { static int x; };
template <typename T> int B<T>::x = f();
template struct __declspec(dllimport) B<int>;
- // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
+ USEVAR(B<int>::x);
+ // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = external dllimport global i32
constexpr int g() { return 42; }
template <typename T> struct C { static int x; };
template <typename T> int C<T>::x = g();
template struct __declspec(dllimport) C<int>;
- // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
+ USEVAR(C<int>::x);
+ // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = external dllimport global i32
template <int I> struct D { static int x, y; };
template <int I> int D<I>::x = I + 1;
template <int I> int D<I>::y = I + f();
template struct __declspec(dllimport) D<42>;
- // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
- // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
+ USEVAR(D<42>::x);
+ USEVAR(D<42>::y);
+ // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32
+ // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32
}
namespace PR21355 {
@@ -737,6 +748,17 @@ namespace PR21366 {
inline void S::outOfClassInlineMethod() {}
}
+namespace PR27319 {
+ // Make sure we don't assert due to not having checked for operator delete on
+ // the destructor.
+ template <typename> struct A {
+ virtual ~A() = default;
+ };
+ extern template struct __declspec(dllimport) A<int>;
+ void f() { new A<int>(); }
+ // MO1-DAG: @"\01??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*]
+}
+
// MS ignores DLL attributes on partial specializations.
template <typename T> struct PartiallySpecializedClassTemplate {};
template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };
@@ -788,6 +810,36 @@ template struct __declspec(dllimport) PR23770DerivedTemplate<int>;
USEMEMFUNC(PR23770BaseTemplate<int>, f);
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ"
+namespace PR27810 {
+ template <class T>
+ struct basic_ostream {
+ struct sentry {
+ sentry() { }
+ void foo() { }
+ };
+ };
+ template class __declspec(dllimport) basic_ostream<char>;
+ // The explicit instantiation definition acts as an explicit instantiation
+ // *declaration*, dllimport is not inherited by the inner class, and no
+ // functions are emitted unless they are used.
+
+ USEMEMFUNC(basic_ostream<char>::sentry, foo);
+ // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?foo@sentry@?$basic_ostream@D@PR27810@@QAEXXZ"
+ // M32-NOT: ??0sentry@?$basic_ostream@D@PR27810@@QAE@XZ
+}
+
+namespace PR27811 {
+ template <class T> struct codecvt {
+ virtual ~codecvt() { }
+ };
+ template class __declspec(dllimport) codecvt<char>;
+
+ // dllimport means this explicit instantiation definition gets treated as a
+ // declaration. Thus, the vtable should not be marked used, and in fact
+ // nothing for this class should be emitted at all since it's not used.
+ // M32-NOT: codecvt
+}
+
//===----------------------------------------------------------------------===//
// Classes with template base classes
//===----------------------------------------------------------------------===//
diff --git a/test/CodeGenCXX/duplicate-mangled-name.cpp b/test/CodeGenCXX/duplicate-mangled-name.cpp
index 104bb6eb4d62..8c8f6e0311c3 100644
--- a/test/CodeGenCXX/duplicate-mangled-name.cpp
+++ b/test/CodeGenCXX/duplicate-mangled-name.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST1
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST2
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST2 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST3
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST4
#ifdef TEST1
@@ -14,28 +16,61 @@ extern "C" {
#elif TEST2
-// We expect no warnings here, as there is only declaration of _ZN1TD1Ev function, no definitions.
+// expected-no-diagnostics
+
+// We expect no warnings here, as there is only declaration of _ZN1TD1Ev
+// function, no definitions.
extern "C" void _ZN1TD1Ev();
struct T {
~T() {}
};
-void foo() {
+// We expect no warnings here, as there is only declaration of _ZN2nm3abcE
+// global, no definitions.
+extern "C" {
+ int _ZN2nm3abcE;
+}
+
+namespace nm {
+ float abc = 2;
+}
+// CHECK: @_ZN2nm3abcE = global float
+
+float foo() {
_ZN1TD1Ev();
+// CHECK: call void bitcast ({{.*}} (%struct.T*)* @_ZN1TD1Ev to void ()*)()
T t;
+// CHECK: call {{.*}} @_ZN1TD1Ev(%struct.T* %t)
+ return _ZN2nm3abcE + nm::abc;
}
+#elif TEST3
+
extern "C" void _ZN2T2D2Ev() {}; // expected-note {{previous definition is here}}
struct T2 {
~T2() {} // expected-error {{definition with same mangled name as another definition}}
};
-void bar() {
+void foo() {
_ZN2T2D2Ev();
T2 t;
}
+#elif TEST4
+
+extern "C" {
+ int _ZN2nm3abcE = 1; // expected-note {{previous definition is here}}
+}
+
+namespace nm {
+ float abc = 2; // expected-error {{definition with same mangled name as another definition}}
+}
+
+float foo() {
+ return _ZN2nm3abcE + nm::abc;
+}
+
#else
#error Unknwon test
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index b44e8144bb27..db0576a1baeb 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -448,5 +448,27 @@ namespace test16 {
}
}
+namespace test17 {
+class BaseException {
+private:
+ int a[4];
+public:
+ BaseException() {};
+};
+
+class DerivedException: public BaseException {
+};
+
+int foo() {
+ throw DerivedException();
+ // The alignment passed to memset is 8, not 16, on Darwin.
+
+ // CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8*
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 8, i1 false)
+}
+}
+
// CHECK: attributes [[NUW]] = { nounwind }
// CHECK: attributes [[NR]] = { noreturn }
diff --git a/test/CodeGenCXX/exceptions-cxx-ehsc.cpp b/test/CodeGenCXX/exceptions-cxx-ehsc.cpp
new file mode 100644
index 000000000000..c660d145393a
--- /dev/null
+++ b/test/CodeGenCXX/exceptions-cxx-ehsc.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fexceptions -fcxx-exceptions -fexternc-nounwind | FileCheck %s
+
+namespace test1 {
+struct Cleanup { ~Cleanup(); };
+extern "C" void never_throws();
+void may_throw();
+
+void caller() {
+ Cleanup x;
+ never_throws();
+ may_throw();
+}
+}
+// CHECK-LABEL: define void @"\01?caller@test1@@YAXXZ"(
+// CHECK: call void @never_throws(
+// CHECK: invoke void @"\01?may_throw@test1@@YAXXZ"(
+
+namespace test2 {
+struct Cleanup { ~Cleanup(); };
+extern "C" void throws_int() throw(int);
+void may_throw();
+
+void caller() {
+ Cleanup x;
+ throws_int();
+ may_throw();
+}
+}
+// CHECK-LABEL: define void @"\01?caller@test2@@YAXXZ"(
+// CHECK: invoke void @throws_int(
+// CHECK: invoke void @"\01?may_throw@test2@@YAXXZ"(
diff --git a/test/CodeGenCXX/exceptions-cxx-new.cpp b/test/CodeGenCXX/exceptions-cxx-new.cpp
index 3767f3321c3e..3329aea32ef2 100644
--- a/test/CodeGenCXX/exceptions-cxx-new.cpp
+++ b/test/CodeGenCXX/exceptions-cxx-new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fexceptions -fcxx-exceptions -fnew-ms-eh -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s
int f(int);
@@ -72,6 +72,6 @@ void test_cleanup() {
// CHECK: ret void
// CHECK: [[TERMINATE]]
-// CHECK: cleanuppad within none []
-// CHECK-NEXT: call void @"\01?terminate@@YAXXZ"()
+// CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none []
+// CHECK-NEXT: call void @"\01?terminate@@YAXXZ"() {{.*}} [ "funclet"(token %[[CLEANUPPAD]]) ]
diff --git a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
index 4e8be72089d5..ab75a87698ab 100644
--- a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -70,14 +70,14 @@ void test_lambda() {
lambda();
}
-// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this)
+// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ"(%class.anon* %this)
// CHECK: @llvm.localescape(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: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer)
-// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %[[fp]], i32 0)
+// CHECK-LABEL: define internal i32 @"\01?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %[[fp]], 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
index abbe95be3404..589bc2265760 100644
--- a/test/CodeGenCXX/exceptions-seh.cpp
+++ b/test/CodeGenCXX/exceptions-seh.cpp
@@ -95,7 +95,7 @@ void use_seh_in_lambda() {
// 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-LABEL: define internal void @"\01??R<lambda_0>@?0??use_seh_in_lambda@@YAXXZ@QEBA@XZ"(%class.anon* %this)
// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// CHECK: invoke void @might_throw() #[[NOINLINE]]
// CHECK: catchpad
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index ff76b11350db..86616d1e2c62 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -30,7 +30,7 @@ namespace test1 {
A *a() {
// CHECK: define [[A:%.*]]* @_ZN5test11aEv()
- // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5)
// CHECK: ret [[A]]* [[CAST]]
@@ -40,7 +40,7 @@ namespace test1 {
A *b() {
// CHECK: define [[A:%.*]]* @_ZN5test11bEv()
- // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
// CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]])
@@ -56,7 +56,7 @@ namespace test1 {
A *c() {
// CHECK: define [[A:%.*]]* @_ZN5test11cEv()
// CHECK: [[ACTIVE:%.*]] = alloca i1
- // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
// CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
@@ -82,7 +82,7 @@ namespace test1 {
A *d() {
// CHECK: define [[A:%.*]]* @_ZN5test11dEv()
// CHECK: [[ACTIVE:%.*]] = alloca i1
- // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
// CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
@@ -100,7 +100,7 @@ namespace test1 {
A *e() {
// CHECK: define [[A:%.*]]* @_ZN5test11eEv()
// CHECK: [[ACTIVE:%.*]] = alloca i1
- // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
// CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
@@ -131,7 +131,7 @@ namespace test1 {
// CHECK: define [[A:%.*]]* @_ZN5test11iEv()
// CHECK: [[X:%.*]] = alloca [[A]]*, align 8
// CHECK: [[ACTIVE:%.*]] = alloca i1
- // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
// CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]])
@@ -422,7 +422,7 @@ namespace test9 {
return new A[10];
}
// CHECK: define {{%.*}}* @_ZN5test94testEv
- // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam
+ // CHECK: [[TEST9_NEW:%.*]] = call i8* @_Znam
// CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]])
}
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 6076444c25b0..7e00d78e4834 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-OPT
// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -O3 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK-MS
// This check logically is attached to 'template int S<int>::i;' below.
// CHECK: @_ZN1SIiE1iE = weak_odr global i32
@@ -103,6 +104,28 @@ int g() { return S<int>().f(); }
template struct S<int>;
}
+namespace NestedClasses {
+ // Check how explicit instantiation of an outer class affects the inner class.
+ template <typename T> struct Outer {
+ struct Inner {
+ void f() {}
+ };
+ };
+
+ // Explicit instantiation definition of Outer causes explicit instantiation
+ // definition of Inner.
+ template struct Outer<int>;
+ // CHECK: define weak_odr void @_ZN13NestedClasses5OuterIiE5Inner1fEv
+ // CHECK-MS: define weak_odr x86_thiscallcc void @"\01?f@Inner@?$Outer@H@NestedClasses@@QAEXXZ"
+
+ // Explicit instantiation declaration of Outer causes explicit instantiation
+ // declaration of Inner, but not in MSVC mode.
+ extern template struct Outer<char>;
+ auto use = &Outer<char>::Inner::f;
+ // CHECK: {{declare|define available_externally}} void @_ZN13NestedClasses5OuterIcE5Inner1fEv
+ // CHECK-MS: define linkonce_odr x86_thiscallcc void @"\01?f@Inner@?$Outer@D@NestedClasses@@QAEXXZ"
+}
+
// Check that we emit definitions from explicit instantiations even when they
// occur prior to the definition itself.
template <typename T> struct S {
diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp
index 5b59a38ba0d7..1046915fcaa2 100644
--- a/test/CodeGenCXX/extern-c.cpp
+++ b/test/CodeGenCXX/extern-c.cpp
@@ -16,8 +16,23 @@ extern "C" struct d;
// CHECK-NOT: should_not_appear
extern "C++" int should_not_appear;
+// CHECK: @_ZN3foo10extern_cxxE = global
+extern "C++" int extern_cxx = 0;
+
}
+// CHECK-NOT: @global_a = global
+extern "C" int global_a;
+
+// CHECK: @global_b = global
+extern "C" int global_b = 0;
+
+// CHECK-NOT: should_not_appear
+extern "C++" int should_not_appear;
+
+// CHECK: @extern_cxx = global
+extern "C++" int extern_cxx = 0;
+
namespace test1 {
namespace {
struct X {};
@@ -59,10 +74,10 @@ extern "C" {
// CHECK-NOT: @unused
// CHECK-NOT: @duplicate_internal
- // CHECK: @internal_var = internal alias i32, i32* @_Z12internal_var
+ // CHECK: @internal_var = internal alias i32, i32* @_ZL12internal_var
// CHECK-NOT: @unused
// CHECK-NOT: @duplicate_internal
- // CHECK: @internal_fn = internal alias i32 (), i32 ()* @_Z11internal_fnv
+ // CHECK: @internal_fn = internal alias i32 (), i32 ()* @_ZL11internal_fnv
// CHECK-NOT: @unused
// CHECK-NOT: @duplicate_internal
}
diff --git a/test/CodeGenCXX/float128-declarations.cpp b/test/CodeGenCXX/float128-declarations.cpp
new file mode 100644
index 000000000000..e1604a61cac7
--- /dev/null
+++ b/test/CodeGenCXX/float128-declarations.cpp
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -emit-llvm -triple powerpc64-unknown-unknown \
+// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \
+// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple i386-unknown-linux-gnu -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux-gnu -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple systemz-unknown-linux-gnu -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-SYSZ
+//
+/* Various contexts where type __float128 can appear. The different check
+ prefixes are due to different mangling on X86 and different calling
+ convention on SystemZ. */
+
+/* Namespace */
+namespace {
+ __float128 f1n;
+ __float128 f2n = 33.q;
+ __float128 arr1n[10];
+ __float128 arr2n[] = { 1.2q, 3.0q, 3.e11q };
+ const volatile __float128 func1n(const __float128 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+/* File */
+__float128 f1f;
+__float128 f2f = 32.4q;
+static __float128 f3f = f2f;
+__float128 arr1f[10];
+__float128 arr2f[] = { -1.2q, -3.0q, -3.e11q };
+__float128 func1f(__float128 arg);
+
+/* Class */
+class C1 {
+ __float128 f1c;
+ static const __float128 f2c;
+ volatile __float128 f3c;
+public:
+ C1(__float128 arg) : f1c(arg), f3c(arg) { }
+ __float128 func1c(__float128 arg ) {
+ return f1c + arg;
+ }
+ static __float128 func2c(__float128 arg) {
+ return arg * C1::f2c;
+ }
+};
+
+/* Template */
+template <class C> C func1t(C arg) { return arg * 2.q; }
+template <class C> struct S1 {
+ C mem1;
+};
+template <> struct S1<__float128> {
+ __float128 mem2;
+};
+
+/* Local */
+int main(void) {
+ __float128 f1l = 123e220q;
+ __float128 f2l = -0.q;
+ __float128 f3l = 1.189731495357231765085759326628007e4932q;
+ C1 c1(f1l);
+ S1<__float128> s1 = { 132.q };
+ __float128 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+#if (__cplusplus >= 201103L)
+ auto f5l = -1.q, *f6l = &f2l, f7l = func1t(f3l);
+#endif
+ __float128 f8l = f4l++;
+ __float128 arr1l[] = { -1.q, -0.q, -11.q };
+}
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
+// CHECK-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128*
+// CHECK-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
+// CHECK-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
+// CHECK-DAG: @arr1f = global [10 x fp128]
+// CHECK-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
+// CHECK-DAG: declare fp128 @_Z6func1fU10__float128(fp128)
+// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128 %arg)
+// CHECK-DAG: define linkonce_odr fp128 @_ZN2C16func2cEU10__float128(fp128 %arg)
+// CHECK-DAG: define linkonce_odr fp128 @_Z6func1tIU10__float128ET_S0_(fp128 %arg)
+// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
+// CHECK-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
+// CHECK-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
+// CHECK-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
+// CHECK-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
+// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
+// CHECK-DAG: store fp128 [[INC]], fp128* %f4l
+
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
+// CHECK-X86-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKg(fp128*
+// CHECK-X86-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
+// CHECK-X86-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
+// CHECK-X86-DAG: @arr1f = global [10 x fp128]
+// CHECK-X86-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
+// CHECK-X86-DAG: declare fp128 @_Z6func1fg(fp128)
+// CHECK-X86-DAG: define linkonce_odr void @_ZN2C1C2Eg(%class.C1* %this, fp128 %arg)
+// CHECK-X86-DAG: define linkonce_odr fp128 @_ZN2C16func2cEg(fp128 %arg)
+// CHECK-X86-DAG: define linkonce_odr fp128 @_Z6func1tIgET_S0_(fp128 %arg)
+// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-X86-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
+// CHECK-X86-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
+// CHECK-X86-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
+// CHECK-X86-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
+// CHECK-X86-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
+// CHECK-X86-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
+// CHECK-X86-DAG: store fp128 [[INC]], fp128* %f4l
+
+// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
+// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
+// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
+// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
+// CHECK-SYSZ-DAG: define internal void @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128*
+// CHECK-SYSZ-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
+// CHECK-SYSZ-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
+// CHECK-SYSZ-DAG: @arr1f = global [10 x fp128]
+// CHECK-SYSZ-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
+// CHECK-SYSZ-DAG: declare void @_Z6func1fU10__float128(fp128*
+// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128*
+// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C16func2cEU10__float128(fp128*
+// CHECK-SYSZ-DAG: define linkonce_odr void @_Z6func1tIU10__float128ET_S0_(fp128*
+// CHECK-SYSZ-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-SYSZ-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
+// CHECK-SYSZ-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
+// CHECK-SYSZ-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
+// CHECK-SYSZ-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
+// CHECK-SYSZ-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
+// CHECK-SYSZ-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
+// CHECK-SYSZ-DAG: store fp128 [[INC]], fp128* %f4l
diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp
index c1a0eeccf811..27bd7affbac9 100644
--- a/test/CodeGenCXX/goto.cpp
+++ b/test/CodeGenCXX/goto.cpp
@@ -18,7 +18,7 @@ namespace test0 {
// CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
// CHECK: call void @_ZN5test01AC1Ev([[A]]* [[Y]])
// CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[Z]])
- // CHECK: [[NEW:%.*]] = invoke noalias i8* @_Znwm(i64 1)
+ // CHECK: [[NEW:%.*]] = invoke i8* @_Znwm(i64 1)
// CHECK: store i1 true, i1* [[CLEANUPACTIVE]]
// CHECK: [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]*
// CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]])
diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp
index 42080a2dafa9..a3adf70ebb18 100644
--- a/test/CodeGenCXX/inheriting-constructor.cpp
+++ b/test/CodeGenCXX/inheriting-constructor.cpp
@@ -1,4 +1,8 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple i386-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple arm64-ehabi -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple i386-windows -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN32
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN64
// PR12219
struct A { A(int); virtual ~A(); };
@@ -11,18 +15,396 @@ struct C { template<typename T> C(T); };
struct D : C { using C::C; };
D d(123);
-// CHECK-LABEL: define void @_ZN1BD2Ev
-// CHECK-LABEL: define void @_ZN1BD1Ev
-// CHECK-LABEL: define void @_ZN1BD0Ev
+// ITANIUM-LABEL: define void @_ZN1BD2Ev
+// ITANIUM-LABEL: define void @_ZN1BD1Ev
+// ITANIUM-LABEL: define void @_ZN1BD0Ev
+// WIN32-LABEL: define {{.*}}void @"\01??1B@@UAE@XZ"
+// WIN64-LABEL: define {{.*}}void @"\01??1B@@UEAA@XZ"
-// CHECK-LABEL: define linkonce_odr void @_ZN1BC1Ei(
-// CHECK: call void @_ZN1BC2Ei(
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI11AEi(
+// ITANIUM: call void @_ZN1BCI21AEi(
-// CHECK-LABEL: define linkonce_odr void @_ZN1DC1IiEET_(
-// CHECK: call void @_ZN1DC2IiEET_(
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI11CIiEET_(
+// ITANIUM: call void @_ZN1DCI21CIiEET_(
-// CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ei(
-// CHECK: call void @_ZN1AC2Ei(
+// WIN32-LABEL: define internal {{.*}} @"\01??0B@@QAE@H@Z"(
+// WIN32: call {{.*}} @"\01??0A@@QAE@H@Z"(
+// WIN64-LABEL: define internal {{.*}} @"\01??0B@@QEAA@H@Z"(
+// WIN64: call {{.*}} @"\01??0A@@QEAA@H@Z"(
-// CHECK-LABEL: define linkonce_odr void @_ZN1DC2IiEET_(
-// CHECK: call void @_ZN1CC2IiEET_(
+// WIN32-LABEL: define internal {{.*}} @"\01??0D@@QAE@H@Z"(
+// WIN32: call {{.*}} @"\01??$?0H@C@@QAE@H@Z"
+// WIN64-LABEL: define internal {{.*}} @"\01??0D@@QEAA@H@Z"(
+// WIN64: call {{.*}} @"\01??$?0H@C@@QEAA@H@Z"
+
+struct Q { Q(int); Q(const Q&); ~Q(); };
+struct Z { Z(); Z(int); ~Z(); int n; };
+
+namespace noninline_nonvirt {
+ struct A { A(int, Q&&, void *__attribute__((pass_object_size(0)))); int n; };
+ struct B : Z, A { Z z; using A::A; };
+ B b(1, 2, &b);
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}} %[[TMP:.*]], i32 2)
+ // ITANIUM: call void @_ZN17noninline_nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0({{.*}} @_ZN17noninline_nonvirt1bE, i32 1, {{.*}} %[[TMP]], i8* {{.*}} @_ZN17noninline_nonvirt1bE{{.*}}, i{{32|64}} 12)
+ // ITANIUM: call void @_ZN1QD1Ev({{.*}} %[[TMP]])
+ // ITANIUM: call i32 @__cxa_atexit(
+
+ // Complete object ctor for B delegates to base object ctor.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} {{.*}})
+
+ // In MSABI, we don't have ctor variants. B ctor forwards to A ctor.
+ // MSABI-LABEL: define internal {{.*}} @"\01??0B@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
+ // MSABI: call {{.*}} @"\01??0A@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
+
+ struct C : B { using B::B; };
+ C c(1, 2, &c);
+ // Complete object ctor for C delegates.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1CCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN17noninline_nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} {{.*}})
+
+ // MSABI-LABEL: define internal {{.*}} @"\01??0C@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: call {{.*}} @"\01??0B@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+}
+
+namespace noninline_virt {
+ struct A { A(int, Q&&, void *__attribute__((pass_object_size(0)))); int n; };
+ struct B : Z, virtual A { Z z; using A::A; };
+ B b(1, 2, &b);
+ // Complete object ctor forwards to A ctor then constructs Zs.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN14noninline_virt1BCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}} %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} %{{.*}}
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1BE
+ // ITANIUM: call void @_ZN1ZC1Ev(
+
+ // MSABI-LABEL: define internal {{.*}} @"\01??0B@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}})
+ // MSABI: %[[COMPLETE:.*]] = icmp ne
+ // MSABI: br i1 %[[COMPLETE]],
+ // MSABI: call {{.*}} @"\01??0A@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: br
+ // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
+ // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
+
+ struct C : B { using B::B; };
+ C c(1, 2, &c);
+ // Complete object ctor forwards to A ctor, then calls B's base inheriting
+ // constructor, which takes no arguments other than the this pointer and VTT.
+ // ITANIUM_LABEL: define linkonce_odr void @_ZN14noninline_virt1CCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}} %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* %{{.*}}, i{{32|64}} %{{.*}})
+ // ITANIUM: call void @_ZN14noninline_virt1BCI2NS_1AEEiO1QPvU17pass_object_size0(%{{.*}}* %{{.*}}, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN14noninline_virt1CE, i64 0, i64 1))
+ // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1CE
+
+ // C constructor forwards to B constructor and A constructor. We pass the args
+ // to both. FIXME: Can we pass undef here instead, for the base object
+ // constructor call?
+ // MSABI-LABEL: define internal {{.*}} @"\01??0C@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}})
+ // MSABI: %[[COMPLETE:.*]] = icmp ne
+ // MSABI: br i1 %[[COMPLETE]],
+ // MSABI: call {{.*}} @"\01??0A@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: br
+ // MSABI: call {{.*}} @"\01??0B@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 0)
+}
+
+// For MSABI only, check that inalloca arguments result in inlining.
+namespace inalloca_nonvirt {
+ struct A { A(Q, int, Q, Q&&); int n; };
+ struct B : Z, A { Z z; using A::A; };
+ B b(1, 2, 3, 4);
+ // No inlining implied for Itanium.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN16inalloca_nonvirt1BCI1NS_1AEE1QiS1_OS1_(
+ // ITANIUM: call void @_ZN16inalloca_nonvirt1BCI2NS_1AEE1QiS1_OS1_(
+
+ // MSABI-LABEL: define internal void @"\01??__Eb@inalloca_nonvirt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"\01??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"\01??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4);
+ // MSABI-LABEL: define internal void @"\01??__Ec@inalloca_nonvirt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"\01??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"\01??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+}
+
+namespace inalloca_virt {
+ struct A { A(Q, int, Q, Q&&); int n; };
+ struct B : Z, virtual A { Z z; using A::A; };
+ B b(1, 2, 3, 4);
+
+ // MSABI-LABEL: define internal void @"\01??__Eb@inalloca_virt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // FIXME: It's dumb to round-trip this though memory and generate a branch.
+ // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
+ // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
+ // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
+ // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
+ //
+ // WIN32: store {{.*}} @"\01??_8B@inalloca_virt@@7B@"
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"\01??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: br
+ //
+ // Note that if we jumped directly to here we would fail to stackrestore and
+ // destroy the parameters, but that's not actually possible.
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: br i1
+ // WIN64: call {{.*}} @"\01??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: br
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4);
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN13inalloca_virt1CD1Ev(
+
+ // MSABI-LABEL: define internal void @"\01??__Ec@inalloca_virt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"\01??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
+ // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
+ // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
+ // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
+ //
+ // WIN32: store {{.*}} @"\01??_8C@inalloca_virt@@7B@"
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"\01??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: br
+ //
+ // WIN32: store i32 0, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
+ // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
+ // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
+ // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
+ //
+ // Note: this block is unreachable.
+ // WIN32: store {{.*}} @"\01??_8B@inalloca_virt@@7B@"
+ // WIN32: br
+ //
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"\01??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"\01??_DQ@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"\01??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: br i1
+ // WIN64: store {{.*}} @"\01??_8C@inalloca_virt@@7B@"
+ // WIN64: call {{.*}} @"\01??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: br
+ // WIN64: br i1
+ // (Unreachable block)
+ // WIN64: store {{.*}} @"\01??_8B@inalloca_virt@@7B@"
+ // WIN64: br
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"\01??0Z@@QEAA@XZ"(
+ // WIN64: call void @"\01??_DQ@@QEAA@XZ"({{.*}}* %[[TMP]])
+}
+
+namespace inline_nonvirt {
+ struct A { A(Q, int, Q, Q&&, ...); int n; };
+ struct B : Z, A { Z z; using A::A; };
+ B b(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor.
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} 4
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %[[THIS]], i32 0, i32 2
+ // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]])
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor.
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} 4
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %{{.*}}, i32 0, i32 2
+ // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]])
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+}
+
+namespace inline_virt {
+ struct A { A(Q, int, Q, Q&&, ...); int n; };
+ struct B : Z, virtual A { Z z; using A::A; };
+ B b(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor.
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} {{12|16}}
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: call void @_ZN1ZC1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor, except that we can just call the
+ // B base inheriting constructor to construct that portion (it doesn't need
+ // the forwarded arguments).
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} {{12|16}}
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: call void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z({{[^,]*}}, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN11inline_virt1CE, i64 0, i64 1))
+ // ITANIUM: store {{.*}} @_ZTVN11inline_virt1CE
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+
+ // B base object inheriting constructor does not get passed arguments.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z(
+ // ITANIUM-NOT: call
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM-NOT: call
+ // VTT -> vtable
+ // ITANIUM: store
+ // ITANIUM-NOT: call
+ // ITANIUM: call void @_ZN1ZC1Ev(
+ // ITANIUM-NOT: call
+ // ITANIUM: }
+}
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI21AEi(
+// ITANIUM: call void @_ZN1AC2Ei(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI21CIiEET_(
+// ITANIUM: call void @_ZN1CC2IiEET_(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0(
+// ITANIUM: call void @_ZN1ZC2Ev(
+// ITANIUM: call void @_ZN17noninline_nonvirt1AC2EiO1QPvU17pass_object_size0(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0(
+// ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0(
diff --git a/test/CodeGenCXX/init-invariant.cpp b/test/CodeGenCXX/init-invariant.cpp
index 7f348257f263..71eb7dd73492 100644
--- a/test/CodeGenCXX/init-invariant.cpp
+++ b/test/CodeGenCXX/init-invariant.cpp
@@ -56,5 +56,5 @@ void e() {
// CHECK-LABEL: define void @_Z1ev(
// CHECK: call void @_ZN1AC1Ev(%struct.A* nonnull @_ZZ1evE1a)
-// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* nonnull bitcast ({{.*}} @_ZZ1evE1a to i8*))
+// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* {{.*}}bitcast ({{.*}} @_ZZ1evE1a to i8*))
// CHECK-NOT: llvm.invariant.end
diff --git a/test/CodeGenCXX/inline-hint.cpp b/test/CodeGenCXX/inline-hint.cpp
new file mode 100644
index 000000000000..9c14032f9f69
--- /dev/null
+++ b/test/CodeGenCXX/inline-hint.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-hint-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -fno-inline -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NOINLINE
+
+// Force non-trivial implicit constructors/destructors/operators for B by having explicit ones for A
+struct A {
+ A() {}
+ A(const A&) {}
+ A& operator=(const A&) { return *this; }
+ ~A() {}
+};
+
+struct B {
+ A member;
+ int implicitFunction(int a) { return a + a; }
+ inline int explicitFunction(int a);
+ int noHintFunction(int a);
+ __attribute__((optnone)) int optNoneFunction(int a) { return a + a; }
+ template<int N> int implicitTplFunction(int a) { return N + a; }
+ template<int N> inline int explicitTplFunction(int a) { return N + a; }
+ template<int N> int noHintTplFunction(int a);
+ template<int N> int explicitRedeclTplFunction(int a);
+};
+
+int B::explicitFunction(int a) { return a + a; }
+// CHECK: @_ZN1B14noHintFunctionEi({{.*}}) [[NOHINT_ATTR:#[0-9]+]]
+int B::noHintFunction(int a) { return a + a; }
+
+// CHECK: @_ZN1B19implicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::implicitTplFunction<0>(int a) { return a + a; }
+// CHECK: @_ZN1B19explicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::explicitTplFunction<0>(int a) { return a + a; }
+// CHECK: @_ZN1B17noHintTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::noHintTplFunction<0>(int a) { return a + a; }
+template<> inline int B::implicitTplFunction<1>(int a) { return a; }
+template<> inline int B::explicitTplFunction<1>(int a) { return a; }
+template<> inline int B::noHintTplFunction<1>(int a) { return a; }
+template<int N> int B::noHintTplFunction(int a) { return N + a; }
+template<int N> inline int B::explicitRedeclTplFunction(int a) { return N + a; }
+
+constexpr int constexprFunction(int a) { return a + a; }
+
+void foo()
+{
+// CHECK: @_ZN1BC1Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR:#[0-9]+]]
+ B b1;
+// CHECK: @_ZN1BC1ERKS_({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+ B b2(b1);
+// CHECK: @_ZN1BaSERKS_({{.*}}) [[IMPLICIT_CONSTR_ATTR]]
+ b2 = b1;
+// CHECK: @_ZN1B16implicitFunctionEi({{.*}}) [[IMPLICIT_ATTR:#[0-9]+]]
+ b1.implicitFunction(1);
+// CHECK: @_ZN1B16explicitFunctionEi({{.*}}) [[EXPLICIT_ATTR:#[0-9]+]]
+ b1.explicitFunction(2);
+ b1.noHintFunction(3);
+// CHECK: @_ZN1B15optNoneFunctionEi({{.*}}) [[OPTNONE_ATTR:#[0-9]+]]
+ b1.optNoneFunction(4);
+// CHECK: @_Z17constexprFunctioni({{.*}}) [[IMPLICIT_ATTR]]
+ constexprFunction(5);
+ b1.implicitTplFunction<0>(6);
+// CHECK: @_ZN1B19implicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.implicitTplFunction<1>(7);
+// CHECK: @_ZN1B19implicitTplFunctionILi2EEEii({{.*}}) [[IMPLICIT_ATTR]]
+ b1.implicitTplFunction<2>(8);
+ b1.explicitTplFunction<0>(9);
+// CHECK: @_ZN1B19explicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitTplFunction<1>(10);
+// CHECK: @_ZN1B19explicitTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitTplFunction<2>(11);
+ b1.noHintTplFunction<0>(12);
+// CHECK: @_ZN1B17noHintTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.noHintTplFunction<1>(13);
+// CHECK: @_ZN1B17noHintTplFunctionILi2EEEii({{.*}}) [[NOHINT_ATTR]]
+ b1.noHintTplFunction<2>(14);
+// CHECK: @_ZN1B25explicitRedeclTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitRedeclTplFunction<2>(15);
+// CHECK: @_ZN1BD2Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+}
+
+// SUITABLE-NOT: attributes [[NOHINT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+// NOINLINE-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[IMPLICIT_CONSTR_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[EXPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[EXPLICIT_ATTR]] = { noinline{{.*}} }
+
+// CHECK-DAG: attributes [[OPTNONE_ATTR]] = { noinline{{.*}} }
diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp
index 4df44f4c5f7f..f59d360314e4 100644
--- a/test/CodeGenCXX/lambda-expressions.cpp
+++ b/test/CodeGenCXX/lambda-expressions.cpp
@@ -12,12 +12,16 @@ extern "C" auto cvar = []{};
// CHECK-LABEL: define i32 @_Z9ARBSizeOfi(i32
int ARBSizeOf(int n) {
- typedef double (T)[8][n];
- using TT = double [8][n];
+ typedef double(T)[8][n];
+ using TT = double[8][n];
return [&]() -> int {
typedef double(T1)[8][n];
using TT1 = double[8][n];
- return sizeof(T) + sizeof(T1) + sizeof(TT) + sizeof(TT1);
+ return [&n]() -> int {
+ typedef double(T2)[8][n];
+ using TT2 = double[8][n];
+ return sizeof(T) + sizeof(T1) + sizeof(T2) + sizeof(TT) + sizeof(TT1) + sizeof(TT2);
+ }();
}();
}
diff --git a/test/CodeGenCXX/linetable-virtual-variadic.cpp b/test/CodeGenCXX/linetable-virtual-variadic.cpp
index 8d1bf47814f8..6f966416867a 100644
--- a/test/CodeGenCXX/linetable-virtual-variadic.cpp
+++ b/test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -15,9 +15,5 @@ void Derived::VariadicFunction(...) { }
// CHECK-LABEL: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz(
// CHECK: ret void, !dbg ![[LOC:[0-9]+]]
//
-// CHECK: !llvm.dbg.cu = !{![[CU:[0-9]+]]}
-//
-// CHECK: ![[CU]] = distinct !DICompileUnit({{.*}} subprograms: ![[SPs:[0-9]+]]
-// CHECK: ![[SPs]] = !{![[SP]]}
// CHECK: ![[SP]] = distinct !DISubprogram(name: "VariadicFunction"
// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]])
diff --git a/test/CodeGenCXX/lto-visibility-inference.cpp b/test/CodeGenCXX/lto-visibility-inference.cpp
new file mode 100644
index 000000000000..8e57ef5e0b89
--- /dev/null
+++ b/test/CodeGenCXX/lto-visibility-inference.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -std=c++11 -fms-extensions -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ITANIUM %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-STD %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -flto-visibility-public-std -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-NOSTD %s
+
+struct C1 {
+ virtual void f();
+};
+
+struct __attribute__((visibility("default"))) C2 {
+ virtual void f();
+};
+
+struct __declspec(dllexport) C3 {
+ virtual void f();
+};
+
+struct __declspec(dllimport) C4 {
+ virtual void f();
+};
+
+struct [[clang::lto_visibility_public]] C5 {
+ virtual void f();
+};
+
+struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) C6 {
+ virtual void f();
+};
+
+namespace std {
+
+struct C7 {
+ virtual void f();
+ struct C8 {
+ virtual void f();
+ };
+};
+
+}
+
+extern "C++" {
+
+namespace stdext {
+
+struct C9 {
+ virtual void f();
+};
+
+}
+
+}
+
+namespace other {
+
+struct C10 {
+ virtual void f();
+};
+
+}
+
+namespace {
+
+struct C11 {
+ virtual void f();
+};
+
+}
+
+void f(C1 *c1, C2 *c2, C3 *c3, C4 *c4, C5 *c5, C6 *c6, std::C7 *c7,
+ std::C7::C8 *c8, stdext::C9 *c9, other::C10 *c10) {
+ // ITANIUM: type.test{{.*}}!"_ZTS2C1"
+ // MS: type.test{{.*}}!"?AUC1@@"
+ c1->f();
+ // ITANIUM-NOT: type.test{{.*}}!"_ZTS2C2"
+ // MS: type.test{{.*}}!"?AUC2@@"
+ c2->f();
+ // ITANIUM: type.test{{.*}}!"_ZTS2C3"
+ // MS-NOT: type.test{{.*}}!"?AUC3@@"
+ c3->f();
+ // ITANIUM: type.test{{.*}}!"_ZTS2C4"
+ // MS-NOT: type.test{{.*}}!"?AUC4@@"
+ c4->f();
+ // ITANIUM-NOT: type.test{{.*}}!"_ZTS2C5"
+ // MS-NOT: type.test{{.*}}!"?AUC5@@"
+ c5->f();
+ // ITANIUM-NOT: type.test{{.*}}!"_ZTS2C6"
+ // MS-NOT: type.test{{.*}}!"?AUC6@@"
+ c6->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSSt2C7"
+ // MS-STD: type.test{{.*}}!"?AUC7@std@@"
+ // MS-NOSTD-NOT: type.test{{.*}}!"?AUC7@std@@"
+ c7->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSNSt2C72C8E"
+ // MS-STD: type.test{{.*}}!"?AUC8@C7@std@@"
+ // MS-NOSTD-NOT: type.test{{.*}}!"?AUC8@C7@std@@"
+ c8->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSN6stdext2C9E"
+ // MS-STD: type.test{{.*}}!"?AUC9@stdext@@"
+ // MS-NOSTD-NOT: type.test{{.*}}!"?AUC9@stdext@@"
+ c9->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSN5other3C10E"
+ // MS: type.test{{.*}}!"?AUC10@other@@"
+ c10->f();
+ // ITANIUM: type.test{{.*}}!{{[0-9]}}
+ // MS: type.test{{.*}}!{{[0-9]}}
+ C11 *c11;
+ c11->f();
+}
diff --git a/test/CodeGenCXX/mangle-abi-tag.cpp b/test/CodeGenCXX/mangle-abi-tag.cpp
new file mode 100644
index 000000000000..385a16f26a51
--- /dev/null
+++ b/test/CodeGenCXX/mangle-abi-tag.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-linux-gnu -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple powerpc64le-unknown-linux-gnu -std=c++11 -o - | FileCheck %s
+
+struct __attribute__((abi_tag("A", "B"))) A { };
+
+struct B: A { };
+
+template<class T>
+
+struct C {
+};
+
+struct D { A* p; };
+
+template<class T>
+struct __attribute__((abi_tag("C", "D"))) E {
+};
+
+struct __attribute__((abi_tag("A", "B"))) F { };
+
+A a1;
+// CHECK-DAG: @_Z2a1B1AB1B =
+
+__attribute__((abi_tag("C", "D")))
+A a2;
+// CHECK-DAG: @_Z2a2B1AB1BB1CB1D =
+
+B a3;
+// CHECK-DAG: @a3 =
+
+C<A> a4;
+// CHECK-DAG: @_Z2a4B1AB1B =
+
+D a5;
+// CHECK-DAG: @a5 =
+
+E<int> a6;
+// CHECK-DAG: @_Z2a6B1CB1D =
+
+E<A> a7;
+// CHECK-DAG: @_Z2a7B1AB1BB1CB1D =
+
+template<>
+struct E<float> {
+ static float a8;
+};
+float E<float>::a8;
+// CHECK-DAG: @_ZN1EB1CB1DIfE2a8E =
+
+template<>
+struct E<F> {
+ static bool a9;
+};
+bool E<F>::a9;
+// CHECK-DAG: @_ZN1EB1CB1DI1FB1AB1BE2a9E =
+
+struct __attribute__((abi_tag("A", "B"))) A10 {
+ virtual ~A10() {}
+} a10;
+// vtable
+// CHECK-DAG: @_ZTV3A10B1AB1B =
+// typeinfo
+// CHECK-DAG: @_ZTI3A10B1AB1B =
+
+struct __attribute__((abi_tag("A"))) B11 {
+ static A10 b;
+};
+A10 B11::b;
+// B11[abi:A]::b[abi:B]
+// CHECK-DAG: @_ZN3B11B1A1bB1BE =
+
+__attribute__ ((abi_tag("C", "D")))
+void* f1() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv(
+
+__attribute__ ((abi_tag("C", "D")))
+A* f2() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv(
+
+B* f3() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f3v(
+
+C<A>* f4() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv(
+
+D* f5() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f5v(
+
+E<char>* f6() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv(
+
+E<A>* f7() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv(
+
+void f8(E<A>*) {
+}
+// CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE(
+
+inline namespace Names1 __attribute__((__abi_tag__)) {
+ class C1 {};
+}
+C1 f9() { return C1(); }
+// CHECK-DAG: @_Z2f9B6Names1v(
+
+inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) {
+ class C2 {};
+}
+C2 f10() { return C2(); }
+// CHECK-DAG: @_Z3f10B4Tag1B4Tag2v(
+
+void __attribute__((abi_tag("A"))) f11(A) {}
+// f11[abi:A](A[abi:A][abi:B])
+// CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B(
+
+A f12(A) { return A(); }
+// f12(A[abi:A][abi:B])
+// CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B(
+
+inline void f13() {
+ struct L {
+ static E<int>* foo() {
+ static A10 a;
+ return 0;
+ }
+ };
+ L::foo();
+}
+void f13_test() {
+ f13();
+}
+// f13()::L::foo[abi:C][abi:D]()
+// CHECK-DAG: define linkonce_odr %struct.E* @_ZZ3f13vEN1L3fooB1CB1DEv(
+
+// f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
+// CHECK-DAG: @_ZZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
+
+// guard variable for f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
+// CHECK-DAG: @_ZGVZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
+
+struct __attribute__((abi_tag("TAG"))) A14 {
+ A14 f14();
+};
+A14 A14::f14() {
+ return A14();
+}
+// A14[abi:TAG]::f14()
+// CHECK-DAG: define {{.+}} @_ZN3A14B3TAG3f14Ev(
+
+template<class T>
+T f15() {
+ return T();
+}
+void f15_test() {
+ f15<A14>();
+}
+// A14[abi:TAG] f15<A14[abi:TAG]>()
+// CHECK-DAG: define linkonce_odr {{.+}} @_Z3f15I3A14B3TAGET_v(
+
+template<class T>
+A14 f16() {
+ return A14();
+}
+void f16_test() {
+ f16<int>();
+}
+// A14[abi:TAG] f16<int>()
+// CHECK-DAG: define linkonce_odr {{.+}} @_Z3f16IiE3A14B3TAGv(
+
+template<class T>
+struct __attribute__((abi_tag("TAG"))) A17 {
+ A17 operator+(const A17& a) {
+ return a;
+ }
+};
+void f17_test() {
+ A17<int> a, b;
+ a + b;
+}
+// A17[abi:TAG]<int>::operator+(A17[abi:TAG]<int> const&)
+// CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A17B3TAGIiEplERKS0_(
+
+struct A18 {
+ operator A() { return A(); }
+};
+void f18_test() {
+ A a = A18();
+}
+// A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice!
+// CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv(
diff --git a/test/CodeGenCXX/mangle-address-space.cpp b/test/CodeGenCXX/mangle-address-space.cpp
index f18480de83de..cd10384594ea 100644
--- a/test/CodeGenCXX/mangle-address-space.cpp
+++ b/test/CodeGenCXX/mangle-address-space.cpp
@@ -10,3 +10,6 @@ typedef OpaqueType __attribute__((address_space(100))) * OpaqueTypePtr;
// CHECK-LABEL: define {{.*}}void @_Z2f0PU5AS10010OpaqueType
void f0(OpaqueTypePtr) { }
+
+// CHECK-LABEL: define {{.*}}void @_Z2f1PU3AS1Kc
+void f1(char __attribute__((address_space(1))) const *p) {} \ No newline at end of file
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index 999def87fc5e..8e2577b03e26 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -166,14 +166,14 @@ inline int define_lambda() {
static auto lambda = [] { static int local; ++local; return local; };
// First, we have the static local variable of type "<lambda_1>" inside of
// "define_lambda".
-// CHECK-DAG: @"\01?lambda@?1??define_lambda@@YAHXZ@4V<lambda_1>@?1@YAHXZ@A"
+// CHECK-DAG: @"\01?lambda@?1??define_lambda@@YAHXZ@4V<lambda_1>@?0??1@YAHXZ@A"
// Next, we have the "operator()" for "<lambda_1>" which is inside of
// "define_lambda".
-// CHECK-DAG: @"\01??R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ"
+// CHECK-DAG: @"\01??R<lambda_1>@?0??define_lambda@@YAHXZ@QBE@XZ"
// Finally, we have the local which is inside of "<lambda_1>" which is inside of
// "define_lambda". Hooray.
-// 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"
+// MSVC2013-DAG: @"\01?local@?2???R<lambda_1>@?0??define_lambda@@YAHXZ@QBE@XZ@4HA"
+// MSVC2015-DAG: @"\01?local@?1???R<lambda_1>@?0??define_lambda@@YAHXZ@QBE@XZ@4HA"
return lambda();
}
@@ -182,12 +182,12 @@ void use_lambda_arg(T) {}
inline void call_with_lambda_arg1() {
use_lambda_arg([]{});
- // CHECK-DAG: @"\01??$use_lambda_arg@V<lambda_1>@?call_with_lambda_arg1@@YAXXZ@@@YAXV<lambda_1>@?call_with_lambda_arg1@@YAXXZ@@Z"
+ // CHECK-DAG: @"\01??$use_lambda_arg@V<lambda_1>@?0??call_with_lambda_arg1@@YAXXZ@@@YAXV<lambda_1>@?0??call_with_lambda_arg1@@YAXXZ@@Z"
}
inline void call_with_lambda_arg2() {
use_lambda_arg([]{});
- // CHECK-DAG: @"\01??$use_lambda_arg@V<lambda_1>@?call_with_lambda_arg2@@YAXXZ@@@YAXV<lambda_1>@?call_with_lambda_arg2@@YAXXZ@@Z"
+ // CHECK-DAG: @"\01??$use_lambda_arg@V<lambda_1>@?0??call_with_lambda_arg2@@YAXXZ@@@YAXV<lambda_1>@?0??call_with_lambda_arg2@@YAXXZ@@Z"
}
int call_lambda() {
@@ -286,3 +286,35 @@ static union {
};
// CHECK-DAG: @"\01??$f@T<unnamed-type-$S1>@PR18204@@@PR18204@@YAHPAT<unnamed-type-$S1>@0@@Z"
}
+
+int PR26105() {
+ auto add = [](int x) { return ([x](int y) { return x + y; }); };
+ return add(3)(4);
+}
+// CHECK-DAG: @"\01??R<lambda_0>@?0??PR26105@@YAHXZ@QBE@H@Z"
+// CHECK-DAG: @"\01??R<lambda_1>@?0???R<lambda_0>@?0??PR26105@@YAHXZ@QBE@H@Z@QBE@H@Z"
+
+int __unaligned * unaligned_foo1() { return 0; }
+int __unaligned * __unaligned * unaligned_foo2() { return 0; }
+__unaligned int unaligned_foo3() { return 0; }
+void unaligned_foo4(int __unaligned *p1) {}
+void unaligned_foo5(int __unaligned * __restrict p1) {}
+template <typename T> T unaligned_foo6(T t) { return t; }
+void unaligned_foo7() { unaligned_foo6<int *>(0); unaligned_foo6<int __unaligned *>(0); }
+
+// CHECK-DAG: @"\01?unaligned_foo1@@YAPFAHXZ"
+// CHECK-DAG: @"\01?unaligned_foo2@@YAPFAPFAHXZ"
+// CHECK-DAG: @"\01?unaligned_foo3@@YAHXZ"
+// CHECK-DAG: @"\01?unaligned_foo4@@YAXPFAH@Z"
+// CHECK-DAG: @"\01?unaligned_foo5@@YAXPIFAH@Z"
+// CHECK-DAG: @"\01??$unaligned_foo6@PAH@@YAPAHPAH@Z"
+// CHECK-DAG: @"\01??$unaligned_foo6@PFAH@@YAPFAHPFAH@Z"
+
+// __unaligned qualifier for function types
+struct unaligned_foo8_S {
+ void unaligned_foo8() volatile __unaligned;
+};
+void unaligned_foo8_S::unaligned_foo8() volatile __unaligned {}
+
+// CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
+
diff --git a/test/CodeGenCXX/mangle-ms-cxx14.cpp b/test/CodeGenCXX/mangle-ms-cxx14.cpp
index 9d30c406c8c7..798a390aeaaa 100644
--- a/test/CodeGenCXX/mangle-ms-cxx14.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx14.cpp
@@ -35,12 +35,12 @@ auto TemplateFuncionWithLocalLambda(T) {
return LocalLambdaWithLocalType();
}
-// 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"
+// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
// CHECK-DAG: "\01??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z"
-// CHECK-DAG: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?1@XZ"
+// CHECK-DAG: "\01??R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?1@XZ"
auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0);
struct S;
@@ -55,3 +55,8 @@ struct Foo {};
Foo<&x<int>, &x<int>> Zoo;
// CHECK-DAG: "\01?Zoo@@3U?$Foo@$1??$x@H@@3HA$1?1@3HA@@A"
+
+template <typename T> T unaligned_x;
+extern auto test_unaligned() { return unaligned_x<int __unaligned *>; }
+// CHECK-DAG: "\01??$unaligned_x@PFAH@@3PFAHA"
+
diff --git a/test/CodeGenCXX/mangle-ms-md5.cpp b/test/CodeGenCXX/mangle-ms-md5.cpp
new file mode 100644
index 000000000000..aef268304832
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-md5.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple i686-pc-win32 %s | FileCheck %s
+int xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
+// CHECK-DAG: @"\01??@bf7ea7b95f260b0b24e7f1e8fc8370ab@" = global i32 0, align 4
+
+struct yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy {
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy();
+ virtual void f();
+};
+yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy::yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy() {}
+// CHECK-DAG: @"\01??@a6a285da2eea70dba6b578022be61d81@??_R4@" = linkonce_odr constant %rtti.CompleteObjectLocator
+// CHECK-DAG: @"\01??@a6a285da2eea70dba6b578022be61d81@" = unnamed_addr alias
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index c82fca49f613..ee0f50e5e2d3 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -4,6 +4,11 @@
int a;
// CHECK-DAG: @"\01?a@@3HA"
+extern "C++" {
+static int __attribute__((used)) ignore_transparent_context;
+// CHECK-DAG: @ignore_transparent_context
+}
+
namespace N {
int b;
// CHECK-DAG: @"\01?b@N@@3HA"
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 7fa300ae237b..23134693de5c 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -201,3 +201,14 @@ namespace test14 {
int call(bool b) { return inl<void>(b); }
}
+
+namespace std {
+template <class _Tp, _Tp...> struct integer_sequence {};
+}
+
+namespace test15 {
+template <int N>
+__make_integer_seq<std::integer_sequence, int, N> make() {}
+template __make_integer_seq<std::integer_sequence, int, 5> make<5>();
+// CHECK: define weak_odr {{.*}} @_ZN6test154makeILi5EEE18__make_integer_seqISt16integer_sequenceiXT_EEv(
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 5012c3b37981..5d757102ed25 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1101,3 +1101,13 @@ struct c {
// CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut0_E
};
}
+
+namespace test55 {
+enum E { R };
+
+template <typename T>
+void fn(T, __underlying_type(T)) {}
+
+template void fn<E>(E, __underlying_type(E));
+// CHECK-LABEL: @_ZN6test552fnINS_1EEEEvT_U3eutS2_
+}
diff --git a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
index 75c0621347a5..9ef1879ce5f2 100644
--- a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
+++ b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -7,7 +7,7 @@ struct ClassWithoutDtor {
void check_array_no_cookies() {
// CHECK: define void @"\01?check_array_no_cookies@@YAXXZ"() [[NUW:#[0-9]+]]
-// CHECK: call noalias i8* @"\01??_U@YAPAXI@Z"(i32 42)
+// CHECK: call i8* @"\01??_U@YAPAXI@Z"(i32 42)
ClassWithoutDtor *array = new ClassWithoutDtor[42];
// CHECK: call void @"\01??_V@YAXPAX@Z"(
@@ -24,7 +24,7 @@ void check_array_cookies_simple() {
// CHECK: define {{.*}} @"\01?check_array_cookies_simple@@YAXXZ"()
ClassWithDtor *array = new ClassWithDtor[42];
-// CHECK: [[ALLOCATED:%.*]] = call noalias i8* @"\01??_U@YAPAXI@Z"(i32 46)
+// CHECK: [[ALLOCATED:%.*]] = call i8* @"\01??_U@YAPAXI@Z"(i32 46)
// 46 = 42 + size of cookie (4)
// CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32*
// CHECK: store i32 42, i32* [[COOKIE]]
@@ -46,7 +46,7 @@ struct __attribute__((aligned(8))) ClassWithAlignment {
void check_array_cookies_aligned() {
// CHECK: define {{.*}} @"\01?check_array_cookies_aligned@@YAXXZ"()
ClassWithAlignment *array = new ClassWithAlignment[42];
-// CHECK: [[ALLOCATED:%.*]] = call noalias i8* @"\01??_U@YAPAXI@Z"(i32 344)
+// CHECK: [[ALLOCATED:%.*]] = call i8* @"\01??_U@YAPAXI@Z"(i32 344)
// 344 = 42*8 + size of cookie (8, due to alignment)
// CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32*
// CHECK: store i32 42, i32* [[COOKIE]]
diff --git a/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp b/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
index da58c461dcc0..6da7a50b617e 100644
--- a/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
+++ b/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
@@ -2,10 +2,10 @@
// PR15768
-// A trivial 12 byte struct is returned indirectly.
+// A trivial 20 byte struct is returned indirectly and taken as byval.
struct S {
S();
- int a, b, c;
+ int a, b, c, d, e;
};
struct C {
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
index e9eba6ed0b20..f03cd6c5632b 100644
--- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -60,7 +60,7 @@ T* test5(A* x) { return dynamic_cast<T*>(x); }
// 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* nonnull bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* nonnull bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// 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
// CHECK: [[RET:%.*]] = phi %struct.T*
@@ -78,7 +78,7 @@ T* test6(B* x) { return dynamic_cast<T*>(x); }
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* nonnull bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* nonnull bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// 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
// CHECK: [[RET:%.*]] = phi %struct.T*
diff --git a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
index 69ec34754813..ac1321efeae2 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
-// RUN: -mconstructor-aliases -fexceptions -fcxx-exceptions -fnew-ms-eh \
+// RUN: -mconstructor-aliases -fexceptions -fcxx-exceptions \
// RUN: -O1 -disable-llvm-optzns \
// RUN: | FileCheck -check-prefix WIN64 %s
diff --git a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
index bf05c693ec0d..004dc45652e4 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O0 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-optzns %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O3 -check-prefix WIN32-LIFETIME %s
struct A {
A();
@@ -94,40 +95,78 @@ int HasConditionalDeactivatedCleanups(bool cond) {
return (cond ? TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())) : CouldThrow());
}
-// WIN32-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
-// WIN32: alloca i1
-// WIN32: %[[arg1_cond:.*]] = alloca i1
+// WIN32-O0-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
+// WIN32-O0: alloca i1
+// WIN32-O0: %[[arg1_cond:.*]] = alloca i1
// Start all four cleanups as deactivated.
-// WIN32: store i1 false
-// WIN32: store i1 false
-// WIN32: store i1 false
-// WIN32: store i1 false
-// WIN32: br i1
+// WIN32-O0: store i1 false
+// WIN32-O0: store i1 false
+// WIN32-O0: store i1 false
+// WIN32-O0: store i1 false
+// WIN32-O0: br i1
// True condition.
-// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
-// WIN32: store i1 true
-// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z"
-// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
-// WIN32: store i1 true, i1* %[[arg1_cond]]
-// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
-// WIN32: store i1 true
-// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z"
-// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
-// WIN32: store i1 true
-// WIN32: store i1 false, i1* %[[arg1_cond]]
-// WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"
+// WIN32-O0: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O0: store i1 true
+// WIN32-O0: invoke void @"\01?TakeRef@@YAXABUA@@@Z"
+// WIN32-O0: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O0: store i1 true, i1* %[[arg1_cond]]
+// WIN32-O0: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O0: store i1 true
+// WIN32-O0: invoke void @"\01?TakeRef@@YAXABUA@@@Z"
+// WIN32-O0: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O0: store i1 true
+// WIN32-O0: store i1 false, i1* %[[arg1_cond]]
+// WIN32-O0: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"
// False condition.
-// WIN32: invoke i32 @"\01?CouldThrow@@YAHXZ"()
+// WIN32-O0: invoke i32 @"\01?CouldThrow@@YAHXZ"()
// Two normal cleanups for TakeRef args.
-// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
-// WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
-// WIN32: ret i32
+// WIN32-O0: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
+// WIN32-O0-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
+// WIN32-O0: ret i32
//
// Somewhere in the landing pad soup, we conditionally destroy arg1.
-// WIN32: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]]
-// WIN32: br i1 %[[isactive]]
-// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
-// WIN32: }
+// WIN32-O0: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]]
+// WIN32-O0: br i1 %[[isactive]]
+// WIN32-O0: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
+// WIN32-O0: }
+
+// WIN32-O3-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
+// WIN32-O3: alloca i1
+// WIN32-O3: alloca i1
+// WIN32-O3: %[[arg1_cond:.*]] = alloca i1
+// Start all four cleanups as deactivated.
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: br i1
+// True condition.
+// WIN32-O3: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O3: store i1 true
+// WIN32-O3: invoke void @"\01?TakeRef@@YAXABUA@@@Z"
+// WIN32-O3: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O3: store i1 true, i1* %[[arg1_cond]]
+// WIN32-O3: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O3: store i1 true
+// WIN32-O3: invoke void @"\01?TakeRef@@YAXABUA@@@Z"
+// WIN32-O3: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32-O3: store i1 true
+// WIN32-O3: store i1 false, i1* %[[arg1_cond]]
+// WIN32-O3: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"
+// False condition.
+// WIN32-O3: invoke i32 @"\01?CouldThrow@@YAHXZ"()
+// Two normal cleanups for TakeRef args.
+// WIN32-O3: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
+// WIN32-O3-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
+// WIN32-O3: ret i32
+//
+// Somewhere in the landing pad soup, we conditionally destroy arg1.
+// WIN32-O3: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]]
+// WIN32-O3: br i1 %[[isactive]]
+// WIN32-O3: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
+// WIN32-O3: }
namespace crash_on_partial_destroy {
struct A {
@@ -206,3 +245,36 @@ void f() {
// WIN32: cleanuppad
// WIN32: call x86_thiscallcc void @"\01??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}})
// WIN32: cleanupret
+
+namespace lifetime_marker {
+struct C {
+ ~C();
+};
+void g();
+void f() {
+ C c;
+ g();
+}
+
+// WIN32-LIFETIME-LABEL: define void @"\01?f@lifetime_marker@@YAXXZ"()
+// WIN32-LIFETIME: %[[c:.*]] = alloca %"struct.lifetime_marker::C"
+// WIN32-LIFETIME: %[[bc0:.*]] = bitcast %"struct.lifetime_marker::C"* %c to i8*
+// WIN32-LIFETIME: call void @llvm.lifetime.start(i64 1, i8* %[[bc0]])
+// WIN32-LIFETIME: invoke void @"\01?g@lifetime_marker@@YAXXZ"()
+// WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]]
+//
+// WIN32-LIFETIME: [[cont]]
+// WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}})
+// WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8*
+// WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc1]])
+//
+// WIN32-LIFETIME: [[lpad0]]
+// WIN32-LIFETIME-NEXT: cleanuppad
+// WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}})
+// WIN32-LIFETIME: cleanupret {{.*}} unwind label %[[lpad1:[^ ]*]]
+//
+// WIN32-LIFETIME: [[lpad1]]
+// WIN32-LIFETIME-NEXT: cleanuppad
+// WIN32-LIFETIME: %[[bc2:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8*
+// WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc2]])
+}
diff --git a/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp b/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
index 0b8d270e1379..7836dcf32b11 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
@@ -1,5 +1,5 @@
-// 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
+// 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 -check-prefix=CHECK %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 -check-prefix=CHECK %s
void may_throw();
void never_throws() noexcept(true) {
@@ -9,7 +9,8 @@ void never_throws() noexcept(true) {
// CHECK-LABEL: define void @"\01?never_throws@@YAXXZ"()
// CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
// CHECK: invoke void @"\01?may_throw@@YAXXZ"()
-// CHECK: cleanuppad within none []
+// CHECK: %[[cp:.*]] = cleanuppad within none []
// MSVC2013: call void @"\01?terminate@@YAXXZ"()
// MSVC2015: call void @__std_terminate()
+// CHECK-SAME: [ "funclet"(token %[[cp]]) ]
// CHECK-NEXT: unreachable
diff --git a/test/CodeGenCXX/microsoft-abi-extern-template.cpp b/test/CodeGenCXX/microsoft-abi-extern-template.cpp
new file mode 100644
index 000000000000..de46d5b5c37c
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-extern-template.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fno-rtti-data -O1 -disable-llvm-optzns %s -emit-llvm -o - -triple x86_64-windows-msvc | FileCheck %s
+
+// Even though Foo<int> has an extern template declaration, we have to emit our
+// own copy the vftable when emitting the available externally constructor.
+
+// CHECK: @"\01??_7?$Foo@H@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [
+// CHECK-SAME: i8* bitcast (i8* (%struct.Foo*, i32)* @"\01??_G?$Foo@H@@UEAAPEAXI@Z" to i8*)
+// CHECK-SAME: ], comdat
+
+// CHECK-LABEL: define %struct.Foo* @"\01?f@@YAPEAU?$Foo@H@@XZ"()
+// CHECK: call %struct.Foo* @"\01??0?$Foo@H@@QEAA@XZ"(%struct.Foo* %{{.*}})
+
+// CHECK: define available_externally %struct.Foo* @"\01??0?$Foo@H@@QEAA@XZ"(%struct.Foo* returned %this)
+// CHECK: store {{.*}} @"\01??_7?$Foo@H@@6B@"
+
+// CHECK: define linkonce_odr i8* @"\01??_G?$Foo@H@@UEAAPEAXI@Z"(%struct.Foo* %this, i32 %should_call_delete)
+
+struct Base {
+ virtual ~Base();
+};
+template <typename T> struct Foo : Base {
+ Foo() {}
+};
+extern template class Foo<int>;
+Foo<int> *f() { return new Foo<int>(); }
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index fd22c0034203..a3985ba09c02 100755
--- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -3,16 +3,29 @@
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
+struct PR26313_Y;
+typedef void (PR26313_Y::*PR26313_FUNC)();
+struct PR26313_X {
+ PR26313_FUNC *ptr;
+ PR26313_X();
+};
+PR26313_X::PR26313_X() {}
+void PR26313_f(PR26313_FUNC *p) { delete p; }
+
+struct PR26313_Z;
+int PR26313_Z::**a = nullptr;
+int PR26313_Z::*b = *a;
+// CHECK-DAG: @"\01?a@@3PAPQPR26313_Z@@HA" = global %0* null, align 4
+// CHECK-DAG: @"\01?b@@3PQPR26313_Z@@HQ1@" = global { i32, i32, i32 } { i32 0, i32 0, i32 -1 }, align 4
+
namespace PR20947 {
struct A;
int A::**a = nullptr;
-// CHECK: %[[opaque0:.*]] = type opaque
-// CHECK: %[[opaque1:.*]] = type opaque
-// CHECK: @"\01?a@PR20947@@3PAPQA@1@HA" = global %[[opaque0]]* null, align 4
+// CHECK-DAG: @"\01?a@PR20947@@3PAPQA@1@HA" = global %{{.*}}* null, align 4
struct B;
int B::*&b = b;
-// CHECK: @"\01?b@PR20947@@3AAPQB@1@HA" = global %[[opaque1]]* null, align 4
+// CHECK-DAG: @"\01?b@PR20947@@3AAPQB@1@HA" = global %{{.*}}* null, align 4
}
namespace PR20017 {
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index 4c2d8506af70..f7dc52406740 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -22,6 +22,16 @@ struct SmallWithCtor {
int x;
};
+struct Multibyte {
+ char a, b, c, d;
+};
+
+struct Packed {
+ short a;
+ int b;
+ short c;
+};
+
struct SmallWithDtor {
SmallWithDtor();
~SmallWithDtor();
@@ -102,19 +112,30 @@ Big big_return() { return Big(); }
void small_arg(Small s) {}
// LINUX-LABEL: define void @_Z9small_arg5Small(i32 %s.0)
-// WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(%struct.Small* byval align 4 %s)
+// WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.0)
// WIN64: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce)
void medium_arg(Medium 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)
+// WIN32: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i32 %s.0, i32 %s.1)
// WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce)
void small_arg_with_ctor(SmallWithCtor s) {}
// LINUX-LABEL: define void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* byval align 4 %s)
-// WIN32: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(%struct.SmallWithCtor* byval align 4 %s)
+// WIN32: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.0)
// WIN64: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce)
+// FIXME: We could coerce to a series of i32s here if we wanted to.
+void multibyte_arg(Multibyte s) {}
+// LINUX-LABEL: define void @_Z13multibyte_arg9Multibyte(%struct.Multibyte* byval align 4 %s)
+// WIN32: define void @"\01?multibyte_arg@@YAXUMultibyte@@@Z"(%struct.Multibyte* byval align 4 %s)
+// WIN64: define void @"\01?multibyte_arg@@YAXUMultibyte@@@Z"(i32 %s.coerce)
+
+void packed_arg(Packed s) {}
+// LINUX-LABEL: define void @_Z10packed_arg6Packed(%struct.Packed* byval align 4 %s)
+// WIN32: define void @"\01?packed_arg@@YAXUPacked@@@Z"(%struct.Packed* byval align 4 %s)
+// WIN64: define void @"\01?packed_arg@@YAXUPacked@@@Z"(%struct.Packed* %s)
+
// Test that dtors are invoked in the callee.
void small_arg_with_dtor(SmallWithDtor s) {}
// WIN32: define void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca) {{.*}} {
@@ -196,6 +217,28 @@ void big_arg(Big s) {}
// WIN32: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* byval align 4 %s)
// WIN64: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* %s)
+// PR27607: We would attempt to load i32 value out of the reference instead of
+// just loading the pointer from the struct during argument expansion.
+struct RefField {
+ RefField(int &x);
+ int &x;
+};
+void takes_ref_field(RefField s) {}
+// LINUX-LABEL: define void @_Z15takes_ref_field8RefField(%struct.RefField* byval align 4 %s)
+// WIN32: define void @"\01?takes_ref_field@@YAXURefField@@@Z"(i32* %s.0)
+// WIN64: define void @"\01?takes_ref_field@@YAXURefField@@@Z"(i64 %s.coerce)
+
+void pass_ref_field() {
+ int x;
+ takes_ref_field(RefField(x));
+}
+// LINUX-LABEL: define void @_Z14pass_ref_fieldv()
+// LINUX: call void @_Z15takes_ref_field8RefField(%struct.RefField* byval align 4 %{{.*}})
+// WIN32-LABEL: define void @"\01?pass_ref_field@@YAXXZ"()
+// WIN32: call void @"\01?takes_ref_field@@YAXURefField@@@Z"(i32* %{{.*}})
+// WIN64-LABEL: define void @"\01?pass_ref_field@@YAXXZ"()
+// WIN64: call void @"\01?takes_ref_field@@YAXURefField@@@Z"(i64 %{{.*}})
+
class Class {
public:
Small thiscall_method_small() { return Small(); }
@@ -230,12 +273,12 @@ class Class {
void thiscall_method_arg(Small 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)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, i32 %s.0)
// WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUSmall@@@Z"(%class.Class* %this, i32 %s.coerce)
void thiscall_method_arg(SmallWithCtor s) {}
// LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
- // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
+ // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* %this, i32 %s.0)
// WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUSmallWithCtor@@@Z"(%class.Class* %this, i32 %s.coerce)
void thiscall_method_arg(Big s) {}
diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp
index 3fb97b9a3632..a576f0c3d7e3 100644
--- a/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -7,7 +7,7 @@
// RUN: FileCheck --check-prefix DTORS3 %s < %t
// RUN: FileCheck --check-prefix DTORS4 %s < %t
//
-// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti | FileCheck --check-prefix DTORS-X64 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti -std=c++11 | FileCheck --check-prefix DTORS-X64 %s
namespace basic {
@@ -443,6 +443,20 @@ void g() { new MoveOnly(f()); }
// CHECK: store {{.*}} @"\01??_7MoveOnly@implicit_copy_vtable@@6B@"
}
+namespace delegating_ctor {
+struct Y {};
+struct X : virtual Y {
+ X(int);
+ X();
+};
+X::X(int) : X() {}
+}
+// CHECK: define x86_thiscallcc %"struct.delegating_ctor::X"* @"\01??0X@delegating_ctor@@QAE@H@Z"(
+// CHECK: %[[is_most_derived_addr:.*]] = alloca i32, align 4
+// CHECK: store i32 %is_most_derived, i32* %[[is_most_derived_addr]]
+// CHECK: %[[is_most_derived:.*]] = load i32, i32* %[[is_most_derived_addr]]
+// CHECK: call x86_thiscallcc {{.*}}* @"\01??0X@delegating_ctor@@QAE@XZ"({{.*}} i32 %[[is_most_derived]])
+
// Dtor thunks for classes in anonymous namespaces should be internal, not
// linkonce_odr.
namespace {
@@ -471,4 +485,3 @@ class G {
extern void testG() {
G g;
}
-
diff --git a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
index 29b434eaf2c5..0202586c8a62 100644
--- a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
@@ -9,12 +9,14 @@ struct 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: @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA" = 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-DAG: @"\01?$TSS0@?1??h@@YAAAUS@@_N@Z@4HA" = linkonce_odr global i32 0
+// CHECK-DAG: @"\01?i@?1??g1@@YAHXZ@4HA" = internal global i32 0, align 4
+// CHECK-DAG: @"\01?$TSS0@?1??g1@@YAHXZ@4HA" = internal global i32 0, align 4
// CHECK-LABEL: define {{.*}} @"\01?f@@YAAAUS@@XZ"()
// CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
@@ -51,14 +53,14 @@ extern inline S &f() {
// 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: %[[guard:.*]] = load atomic i32, i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA" 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: call void @_Init_thread_header(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
+// CHECK-NEXT: %[[guard2:.*]] = load atomic i32, i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
// CHECK-NEXT: %[[cmp2:.*]] = icmp eq i32 %[[guard2]], -1
// CHECK-NEXT: br i1 %[[cmp2]], label %[[init:.*]], label %[[init_end:.*]]
//
@@ -68,7 +70,7 @@ extern inline S &g() {
//
// 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: call void @_Init_thread_footer(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
// CHECK-NEXT: br label %init.end
//
// CHECK: [[init_end]]:
@@ -76,7 +78,7 @@ extern inline S &g() {
//
// CHECK: [[lpad]]:
// CHECK-NEXT: cleanuppad within none []
-// CHECK: call void @_Init_thread_abort(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ")
+// CHECK: call void @_Init_thread_abort(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
// CHECK-NEXT: cleanupret {{.*}} unwind to caller
return s;
}
@@ -86,3 +88,10 @@ extern inline S&h(bool b) {
static S i;
return b ? j : i;
}
+
+// CHECK-LABEL: define i32 @"\01?g1@@YAHXZ"()
+int f1();
+int g1() {
+ static int i = f1();
+ return i;
+}
diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp
index 080f1a025cd8..7c2e2a8f901e 100644
--- a/test/CodeGenCXX/microsoft-abi-throw.cpp
+++ b/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions -DSTD | 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
@@ -19,6 +20,8 @@
// 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
+// CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
struct N { ~N(); };
@@ -43,6 +46,12 @@ void g(const int *const *y) {
throw y;
}
+void h(__unaligned int * __unaligned *y) {
+ // CHECK-LABEL: @"\01?h@@YAXPFAPFAH@Z"
+ // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIU2PAPFAH)
+ throw y;
+}
+
struct Default {
Default(Default &, int = 42);
};
@@ -97,19 +106,25 @@ void h() {
throw nullptr;
}
+#ifdef STD
namespace std {
template <typename T>
void *__GetExceptionInfo(T);
}
+#else
+template <typename T>
+void *__GetExceptionInfo(T);
+#endif
+using namespace std;
void *GetExceptionInfo_test0() {
// CHECK-LABEL: @"\01?GetExceptionInfo_test0@@YAPAXXZ"
// CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1H to i8*)
- return std::__GetExceptionInfo(0);
+ return __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);
+ return __GetExceptionInfo<void (*)()>(&h);
}
diff --git a/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/test/CodeGenCXX/microsoft-abi-try-throw.cpp
index 6b1d2bf2a513..bf1834e8594e 100644
--- a/test/CodeGenCXX/microsoft-abi-try-throw.cpp
+++ b/test/CodeGenCXX/microsoft-abi-try-throw.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTRY -fnew-ms-eh | FileCheck %s -check-prefix=TRY
+// 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
diff --git a/test/CodeGenCXX/microsoft-abi-typeid.cpp b/test/CodeGenCXX/microsoft-abi-typeid.cpp
index 60c31ab4706c..d73f8483a713 100644
--- a/test/CodeGenCXX/microsoft-abi-typeid.cpp
+++ b/test/CodeGenCXX/microsoft-abi-typeid.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s -fexceptions -fcxx-exceptions | FileCheck %s
struct type_info;
namespace std { using ::type_info; }
@@ -49,3 +49,22 @@ const std::type_info* test5_typeid() { return &typeid(v); }
// CHECK: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* bitcast (%struct.V* @"\01?v@@3UV@@A" to i8*))
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
// CHECK-NEXT: ret %struct.type_info* [[RET]]
+
+namespace PR26329 {
+struct Polymorphic {
+ virtual ~Polymorphic();
+};
+
+void f(const Polymorphic &poly) {
+ try {
+ throw;
+ } catch (...) {
+ Polymorphic cleanup;
+ typeid(poly);
+ }
+}
+// CHECK-LABEL: define void @"\01?f@PR26329@@YAXABUPolymorphic@1@@Z"(
+// CHECK: %[[cs:.*]] = catchswitch within none [label %{{.*}}] unwind to caller
+// CHECK: %[[cp:.*]] = catchpad within %[[cs]] [i8* null, i32 64, i8* null]
+// CHECK: invoke i8* @__RTtypeid(i8* {{.*}}) [ "funclet"(token %[[cp]]) ]
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vbtables.cpp b/test/CodeGenCXX/microsoft-abi-vbtables.cpp
index 9cce6f8698c8..df0689423872 100644
--- a/test/CodeGenCXX/microsoft-abi-vbtables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vbtables.cpp
@@ -537,5 +537,5 @@ template <class> struct B : virtual A {
extern template class B<int>;
template B<int>::B();
-// CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = external unnamed_addr constant [2 x i32]{{$}}
+// CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat
}
diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp
index 340675b188d5..0c9b58bbb4d4 100644
--- a/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -17,9 +17,10 @@ struct __declspec(dllimport) U {
virtual ~U();
} u;
-// RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4U@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+// RTTI-DAG: @"\01??_SU@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_U]], i32 0, i32 1)
-// NO-RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+// NO-RTTI-DAG: @"\01??_SU@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
struct __declspec(dllexport) V {
virtual ~V();
@@ -32,7 +33,7 @@ struct __declspec(dllexport) V {
namespace {
struct W {
- virtual ~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*)]
@@ -48,5 +49,7 @@ template <class> struct Y : virtual X {
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*]
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)], comdat($"\01??_7?$Y@H@@6B@")
+// RTTI-DAG: @"\01??_7?$Y@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_Y]], i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)], comdat
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 8897a384430c..480ae8cfbbec 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -481,3 +481,43 @@ C::C() : B() {}
// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[B_i8]], i32 4
// CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false)
}
+
+namespace pr27621 {
+// Devirtualization through a static_cast used to make us compute the 'this'
+// adjustment for B::g instead of C::g. When we directly call C::g, 'this' is a
+// B*, and the prologue of C::g will adjust it to a C*.
+struct A { virtual void f(); };
+struct B { virtual void g(); };
+struct C final : A, B {
+ virtual void h();
+ void g() override;
+};
+void callit(C *p) {
+ static_cast<B*>(p)->g();
+}
+// CHECK-LABEL: define void @"\01?callit@pr27621@@YAXPAUC@1@@Z"(%"struct.pr27621::C"* %{{.*}})
+// CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
+// CHECK: call x86_thiscallcc void @"\01?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]])
+}
+
+namespace test6 {
+class A {};
+class B : virtual A {};
+class C : virtual B {
+ virtual void m_fn1();
+ float field;
+};
+class D : C {
+ D();
+};
+D::D() : C() {}
+// CHECK-LABEL: define x86_thiscallcc %"class.test6::D"* @"\01??0D@test6@@AAE@XZ"(
+// CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"**
+// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+
+// CHECK: %[[SKIP_VBASES]]
+// CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"*
+// CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8*
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8
+// CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false)
+}
diff --git a/test/CodeGenCXX/microsoft-interface.cpp b/test/CodeGenCXX/microsoft-interface.cpp
index a2dfb6926d81..8f4670a6946a 100644
--- a/test/CodeGenCXX/microsoft-interface.cpp
+++ b/test/CodeGenCXX/microsoft-interface.cpp
@@ -31,10 +31,10 @@ int fn() {
// 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*], [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, i32 0, i32 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*], [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, i32 0, i32 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-templ-uuidof.cpp b/test/CodeGenCXX/microsoft-templ-uuidof.cpp
index 0ee390863837..74d6069bbacf 100644
--- a/test/CodeGenCXX/microsoft-templ-uuidof.cpp
+++ b/test/CodeGenCXX/microsoft-templ-uuidof.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s
struct _GUID;
diff --git a/test/CodeGenCXX/microsoft-uuidof.cpp b/test/CodeGenCXX/microsoft-uuidof.cpp
index 2ac5f1b07999..62e4b880ad46 100644
--- a/test/CodeGenCXX/microsoft-uuidof.cpp
+++ b/test/CodeGenCXX/microsoft-uuidof.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-GUID
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-64
// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -DWRONG_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-WRONG-GUID
#ifdef DEFINE_GUID
@@ -36,6 +37,7 @@ GUID g = __uuidof(S1);
// 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" }, comdat
// CHECK: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4
+// CHECK-64: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 8
const GUID& gr = __uuidof(S1);
// CHECK: @gp = global %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4
diff --git a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
index 1ff01820bb1b..5b245a4aaccd 100644
--- a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
+++ b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
@@ -10,13 +10,13 @@ long *alloc_long() {
return rv;
}
// O32-LABEL: define i32* @_Z10alloc_longv()
-// O32: call noalias i8* @_Znwj(i32 signext 4)
+// O32: call i8* @_Znwj(i32 signext 4)
// N32-LABEL: define i32* @_Z10alloc_longv()
-// N32: call noalias i8* @_Znwj(i32 signext 4)
+// N32: call i8* @_Znwj(i32 signext 4)
// N64-LABEL: define i64* @_Z10alloc_longv()
-// N64: call noalias i8* @_Znwm(i64 zeroext 8)
+// N64: call i8* @_Znwm(i64 zeroext 8)
long *alloc_long_array() {
long *rv = new long[2];
@@ -24,13 +24,13 @@ long *alloc_long_array() {
}
// O32-LABEL: define i32* @_Z16alloc_long_arrayv()
-// O32: call noalias i8* @_Znaj(i32 signext 8)
+// O32: call i8* @_Znaj(i32 signext 8)
// N32-LABEL: define i32* @_Z16alloc_long_arrayv()
-// N32: call noalias i8* @_Znaj(i32 signext 8)
+// N32: call i8* @_Znaj(i32 signext 8)
// N64-LABEL: define i64* @_Z16alloc_long_arrayv()
-// N64: call noalias i8* @_Znam(i64 zeroext 16)
+// N64: call i8* @_Znam(i64 zeroext 16)
#include <stddef.h>
diff --git a/test/CodeGenCXX/multi-dim-operator-new.cpp b/test/CodeGenCXX/multi-dim-operator-new.cpp
index 7a235e83a78d..0dfcffb6aa40 100644
--- a/test/CodeGenCXX/multi-dim-operator-new.cpp
+++ b/test/CodeGenCXX/multi-dim-operator-new.cpp
@@ -43,7 +43,7 @@ int main() {
return 0;
}
-// CHECK: call noalias i8* @_Znam
-// CHECK: call noalias i8* @_Znam
-// CHECK: call noalias i8* @_Znam
+// CHECK: call i8* @_Znam
+// CHECK: call i8* @_Znam
+// CHECK: call i8* @_Znam
diff --git a/test/CodeGenCXX/new-alias.cpp b/test/CodeGenCXX/new-alias.cpp
index 4afd942e3cdb..b21638abbfb6 100644
--- a/test/CodeGenCXX/new-alias.cpp
+++ b/test/CodeGenCXX/new-alias.cpp
@@ -9,5 +9,5 @@ extern "C" char *something(long long x) {
void *operator new(size_t) __attribute__((alias("something")));
// PR16715: don't assert here.
-// CHECK: call noalias i8* @_Znwm(i64 4){{$}}
+// CHECK: call i8* @_Znwm(i64 4){{$}}
int *pr16715 = new int;
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 6b76f471a22b..602f93c34f01 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -14,7 +14,7 @@ void fn(int n) {
// CHECK-LABEL: define void @_Z15const_underflowv
void const_underflow() {
// CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
- // CHECK: call noalias i8* @_Zna{{.}}(i{{32|64}} -1)
+ // CHECK: call i8* @_Zna{{.}}(i{{32|64}} -1)
new int[2] { 1, 2, 3 };
}
@@ -37,7 +37,7 @@ void check_array_value_init() {
struct S;
new (int S::*[3][4][5]) ();
- // CHECK: call noalias i8* @_Zna{{.}}(i{{32 240|64 480}})
+ // CHECK: call i8* @_Zna{{.}}(i{{32 240|64 480}})
// CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 60
// CHECK: phi
diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp
index 9057e049b700..0c4c3c823d19 100644
--- a/test/CodeGenCXX/new-overflow.cpp
+++ b/test/CodeGenCXX/new-overflow.cpp
@@ -17,7 +17,7 @@ namespace test0 {
// CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
// CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
// CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(short s) {
return new elt[s];
@@ -40,7 +40,7 @@ namespace test1 {
// CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
// CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
// CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
elt *test(short s) {
return new elt[s];
@@ -68,7 +68,7 @@ namespace test2 {
// CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
// CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
// CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T8]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T8]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
elt *test(short s) {
return new elt[s];
@@ -87,7 +87,7 @@ namespace test4 {
// CHECK: [[N:%.*]] = sext i16 {{%.*}} to 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]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(short s) {
return new elt[s];
@@ -106,7 +106,7 @@ namespace test5 {
// 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]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(int s) {
return new elt[s];
@@ -128,7 +128,7 @@ namespace test6 {
// CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
// CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
// CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(unsigned short s) {
return new elt[s];
@@ -151,7 +151,7 @@ namespace test7 {
// CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
// CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
// CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
elt *test(unsigned short s) {
return new elt[s];
@@ -176,7 +176,7 @@ namespace test8 {
// CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
// CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
// CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
elt *test(long long s) {
return new elt[s];
@@ -201,7 +201,7 @@ namespace test9 {
// CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
// CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
// CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
- // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
elt *test(unsigned long long s) {
return new elt[s];
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 6d6f70138616..ae2ec1505c5d 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -127,15 +127,15 @@ struct B { int a; };
struct Bmemptr { int Bmemptr::* memptr; int a; };
void t11(int n) {
- // CHECK: call noalias i8* @_Znwm
+ // CHECK: call i8* @_Znwm
// CHECK: call void @llvm.memset.p0i8.i64(
B* b = new B();
- // CHECK: call noalias i8* @_Znam
+ // CHECK: call i8* @_Znam
// CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}}
B *b2 = new B[n]();
- // CHECK: call noalias i8* @_Znam
+ // CHECK: call i8* @_Znam
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
// CHECK: br
Bmemptr *b_memptr = new Bmemptr[n]();
@@ -148,11 +148,11 @@ struct Empty { };
// We don't need to initialize an empty class.
// CHECK-LABEL: define void @_Z3t12v
void t12() {
- // CHECK: call noalias i8* @_Znam
+ // CHECK: call i8* @_Znam
// CHECK-NOT: br
(void)new Empty[10];
- // CHECK: call noalias i8* @_Znam
+ // CHECK: call i8* @_Znam
// CHECK-NOT: br
(void)new Empty[10]();
@@ -162,11 +162,11 @@ void t12() {
// Zero-initialization
// CHECK-LABEL: define void @_Z3t13i
void t13(int n) {
- // CHECK: call noalias i8* @_Znwm
+ // CHECK: call i8* @_Znwm
// CHECK: store i32 0, i32*
(void)new int();
- // CHECK: call noalias i8* @_Znam
+ // CHECK: call i8* @_Znam
// CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}}
(void)new int[n]();
@@ -186,7 +186,7 @@ void f() {
// CHECK: call void @_ZN5AllocD1Ev(
// CHECK: call void @_ZN5AllocdaEPv(i8*
delete[] new Alloc[10][20];
- // CHECK: call noalias i8* @_Znwm
+ // CHECK: call i8* @_Znwm
// CHECK: call void @_ZdlPv(i8*
delete new bool;
// CHECK: ret void
@@ -274,7 +274,7 @@ namespace PR10197 {
// CHECK-LABEL: define weak_odr void @_ZN7PR101971fIiEEvv()
template<typename T>
void f() {
- // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm
+ // CHECK: [[CALL:%.*]] = call i8* @_Znwm
// CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
new T;
// CHECK-NEXT: ret void
@@ -296,7 +296,7 @@ namespace PR11757 {
struct X { X(); X(const X&); };
X* a(X* x) { return new X(X()); }
// CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE
- // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm
+ // CHECK: [[CALL:%.*]] = call i8* @_Znwm
// CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
// CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]])
// CHECK-NEXT: ret {{.*}} [[CASTED]]
@@ -306,7 +306,7 @@ namespace PR13380 {
struct A { A() {} };
struct B : public A { int x; };
// CHECK-LABEL: define i8* @_ZN7PR133801fEv
- // CHECK: call noalias i8* @_Znam(
+ // CHECK: call i8* @_Znam(
// CHECK: call void @llvm.memset.p0i8
// CHECK-NEXT: call void @_ZN7PR133801BC1Ev
void* f() { return new B[2](); }
@@ -320,12 +320,12 @@ namespace N3664 {
// CHECK-LABEL: define void @_ZN5N36641fEv
void f() {
- // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+ // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
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]]
+ // CHECK: call i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]]
int *q = new int[3];
// CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
@@ -337,19 +337,18 @@ namespace N3664 {
(void) new (mpt) int;
}
- // FIXME: Can we mark this noalias?
- // CHECK: declare i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND]]
+ // CHECK: declare noalias i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND]]
// CHECK-LABEL: define void @_ZN5N36641gEv
void g() {
// It's OK for there to be attributes here, so long as we don't have a
// 'builtin' attribute.
- // CHECK: call noalias i8* @_Znwm(i64 4){{$}}
+ // CHECK: call i8* @_Znwm(i64 4){{$}}
int *p = (int*)operator new(4);
// CHECK: call void @_ZdlPv({{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]
operator delete(p);
- // CHECK: call noalias i8* @_Znam(i64 12){{$}}
+ // CHECK: call i8* @_Znam(i64 12){{$}}
int *q = (int*)operator new[](12);
// CHECK: call void @_ZdaPv({{.*}}) [[ATTR_NOUNWIND]]
operator delete [](p);
@@ -362,7 +361,7 @@ namespace N3664 {
namespace builtins {
// CHECK-LABEL: define void @_ZN8builtins1fEv
void f() {
- // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]]
+ // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]]
// CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
__builtin_operator_delete(__builtin_operator_new(4));
}
diff --git a/test/CodeGenCXX/operator-new.cpp b/test/CodeGenCXX/operator-new.cpp
index db56cda6cdd1..dc1c36d8eadb 100644
--- a/test/CodeGenCXX/operator-new.cpp
+++ b/test/CodeGenCXX/operator-new.cpp
@@ -16,7 +16,6 @@ void f1() {
new teste();
}
-
// rdar://5739832 - operator new should check for overflow in multiply.
void *f2(long N) {
return new int[N];
@@ -25,5 +24,8 @@ void *f2(long N) {
// SANE-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1
// SANE-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0
// SANE-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]]
-// SANE-NEXT: call noalias i8* @_Znaj(i32 [[RESULT]])
+// SANE-NEXT: call i8* @_Znaj(i32 [[RESULT]])
}
+
+// SANE: declare noalias i8* @_Znaj(
+// SANENOT: declare i8* @_Znaj(
diff --git a/test/CodeGenCXX/optnone-and-attributes.cpp b/test/CodeGenCXX/optnone-and-attributes.cpp
index 56173b5a3601..870d5e9496f0 100644
--- a/test/CodeGenCXX/optnone-and-attributes.cpp
+++ b/test/CodeGenCXX/optnone-and-attributes.cpp
@@ -79,4 +79,4 @@ int exported_optnone_func(int a) {
// CHECK: attributes [[NORETURN]] = { noinline noreturn {{.*}} optnone
// CHECK: attributes [[DLLIMPORT]] =
-// CHECK-SAME-NOT: optnone
+// CHECK-NOT: optnone
diff --git a/test/CodeGenCXX/optnone-class-members.cpp b/test/CodeGenCXX/optnone-class-members.cpp
index 147b82196766..751f3dd2bf08 100644
--- a/test/CodeGenCXX/optnone-class-members.cpp
+++ b/test/CodeGenCXX/optnone-class-members.cpp
@@ -159,6 +159,6 @@ int bar() {
// CHECK: attributes [[NORMAL]] =
-// CHECK-SAME-NOT: noinline
-// CHECK-SAME-NOT: optnone
+// CHECK-NOT: noinline
+// CHECK-NOT: optnone
// CHECK: attributes [[OPTNONE]] = {{.*}} noinline {{.*}} optnone
diff --git a/test/CodeGenCXX/optnone-def-decl.cpp b/test/CodeGenCXX/optnone-def-decl.cpp
index cb3a67793647..0240189c5089 100644
--- a/test/CodeGenCXX/optnone-def-decl.cpp
+++ b/test/CodeGenCXX/optnone-def-decl.cpp
@@ -91,5 +91,5 @@ int user_of_forceinline_optnone_function() {
// CHECK: attributes [[OPTNONE]] = { noinline nounwind optnone {{.*}} }
// CHECK: attributes [[NORMAL]] =
-// CHECK-SAME-NOT: noinline
-// CHECK-SAME-NOT: optnone
+// CHECK-NOT: noinline
+// CHECK-NOT: optnone
diff --git a/test/CodeGenCXX/optnone-templates.cpp b/test/CodeGenCXX/optnone-templates.cpp
index 45a72b3b1766..9f97d832c1e2 100644
--- a/test/CodeGenCXX/optnone-templates.cpp
+++ b/test/CodeGenCXX/optnone-templates.cpp
@@ -100,5 +100,5 @@ void container3()
// CHECK: attributes [[NORMAL]] =
-// CHECK-SAME-NOT: optnone
+// CHECK-NOT: optnone
// CHECK: attributes [[OPTNONE]] = {{.*}} optnone
diff --git a/test/CodeGenCXX/pass-object-size.cpp b/test/CodeGenCXX/pass-object-size.cpp
index 2c7f9742a8e6..7fd8b599aaa3 100644
--- a/test/CodeGenCXX/pass-object-size.cpp
+++ b/test/CodeGenCXX/pass-object-size.cpp
@@ -43,3 +43,40 @@ void Test() {
(&OvlFoo)(nullptr);
}
}
+
+namespace delegate {
+ struct A {
+ A(void *const p __attribute__((pass_object_size(0))));
+ };
+ A::A(void *const p __attribute__((pass_object_size(0)))) {}
+ // Ensure that we forward the size through a delegating constructor call.
+ // CHECK: define void @_ZN8delegate1AC1EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}})
+ // CHECK: call void @_ZN8delegate1AC2EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}})
+}
+
+namespace variadic {
+// We had an issue where variadic member/operator calls with pass_object_size
+// would cause crashes.
+
+struct AsCtor {
+ AsCtor(const char *const c __attribute__((pass_object_size(0))), double a,
+ ...) {}
+};
+
+struct AsMember {
+ void bar(const char *const c __attribute__((pass_object_size(0))), double a,
+ ...) {}
+ void operator()(const char *const c __attribute__((pass_object_size(0))),
+ double a, ...) {}
+};
+
+// CHECK-LABEL: define void @_ZN8variadic4testEv()
+void test() {
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic6AsCtorC1EPKcU17pass_object_size0dz
+ AsCtor("a", 1.0);
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMember3barEPKcU17pass_object_size0dz
+ AsMember{}.bar("a", 1.0);
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMemberclEPKcU17pass_object_size0dz
+ AsMember{}("a", 1.0);
+}
+}
diff --git a/test/CodeGenCXX/pr20719.cpp b/test/CodeGenCXX/pr20719.cpp
index 208d11135847..1c3b21b0b84e 100644
--- a/test/CodeGenCXX/pr20719.cpp
+++ b/test/CodeGenCXX/pr20719.cpp
@@ -2,8 +2,8 @@
// Make sure that we emit H's constructor twice: once with the first lambda
// inside of 'lep' and again with the second lambda inside of 'lep'.
-// CHECK-DAG: @"\01??0?$H@V<lambda_1>@??$lep@X@@YAXXZ@@@QAE@XZ"
-// CHECK-DAG: @"\01??0?$H@V<lambda_2>@??$lep@X@@YAXXZ@@@QAE@XZ"
+// CHECK-DAG: @"\01??0?$H@V<lambda_1>@?0???$lep@X@@YAXXZ@@@QAE@XZ"
+// CHECK-DAG: @"\01??0?$H@V<lambda_2>@?0???$lep@X@@YAXXZ@@@QAE@XZ"
template <typename>
struct H {
diff --git a/test/CodeGenCXX/pr27030.cpp b/test/CodeGenCXX/pr27030.cpp
new file mode 100644
index 000000000000..5c24051d7a2b
--- /dev/null
+++ b/test/CodeGenCXX/pr27030.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s
+struct A {};
+struct B : A {};
+extern "C" {
+extern int B::*a;
+void test1() { (int A::*)(a); }
+}
+// CHECK-LABEL: define void @test1(
+// CHECK: %[[load:.*]] = load i32, i32* @a
+// CHECK: %[[memptr_cmp:.*]] = icmp ne i32 %[[load]], -1
+// CHECK: br i1 %[[memptr_cmp]]
+
+// CHECK: %[[adj:.*]] = sub nsw i32 %[[load]], 0
+// CHECK: %[[nv_adj:.*]] = select i1 true, i32 %[[adj]], i32 0
+
+// CHECK: %[[memptr_converted:.*]] = phi i32 [ -1, {{.*}} ], [ %[[nv_adj]], {{.*}} ]
diff --git a/test/CodeGenCXX/pr28360.cpp b/test/CodeGenCXX/pr28360.cpp
new file mode 100644
index 000000000000..5d7e1ae0c1fd
--- /dev/null
+++ b/test/CodeGenCXX/pr28360.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple i686-pc-win32 | FileCheck %s
+struct A {
+ void Foo();
+ void Foo(int);
+};
+
+using MpTy = void (A::*)();
+
+void Bar(const MpTy &);
+
+void Baz() { Bar(&A::Foo); }
+
+// CHECK-LABEL: define void @"\01?Baz@@YAXXZ"(
+// CHECK: %[[ref_tmp:.*]] = alloca i8*, align 4
+// CHECK: store i8* bitcast (void (%struct.A*)* @"\01?Foo@A@@QAEXXZ" to i8*), i8** %[[ref_tmp]], align 4
+// CHECK: call void @"\01?Bar@@YAXABQ8A@@AEXXZ@Z"(i8** dereferenceable(4) %[[ref_tmp]])
diff --git a/test/CodeGenCXX/pragma-loop.cpp b/test/CodeGenCXX/pragma-loop.cpp
index b85e0b49b9df..e337913646df 100644
--- a/test/CodeGenCXX/pragma-loop.cpp
+++ b/test/CodeGenCXX/pragma-loop.cpp
@@ -9,6 +9,7 @@ void while_test(int *List, int Length) {
#pragma clang loop interleave_count(4)
#pragma clang loop vectorize_width(4)
#pragma clang loop unroll(full)
+#pragma clang loop distribute(enable)
while (i < Length) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
List[i] = i * 2;
@@ -20,7 +21,7 @@ void while_test(int *List, int Length) {
void do_test(int *List, int Length) {
int i = 0;
-#pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable)
+#pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable) distribute(disable)
do {
// CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
List[i] = i * 2;
@@ -55,7 +56,7 @@ void for_range_test() {
// Verify disable pragma clang loop directive generates correct metadata
void disable_test(int *List, int Length) {
-#pragma clang loop vectorize(disable) unroll(disable)
+#pragma clang loop vectorize(disable) unroll(disable) distribute(disable)
for (int i = 0; i < Length; i++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
List[i] = i * 2;
@@ -157,20 +158,22 @@ void template_test(double *List, int Length) {
for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[WIDTH_4:.*]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[UNROLL_FULL:.*]]}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[WIDTH_4:.*]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[UNROLL_FULL:.*]], ![[DISTRIBUTE_ENABLE:.*]]}
// CHECK: ![[WIDTH_4]] = !{!"llvm.loop.vectorize.width", i32 4}
// CHECK: ![[INTERLEAVE_4]] = !{!"llvm.loop.interleave.count", i32 4}
// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
-// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_DISABLE:.*]]}
+// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[DISTRIBUTE_DISABLE]] = !{!"llvm.loop.distribute.enable", i1 false}
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]], ![[INTENABLE_1:.*]]}
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]]}
// CHECK: ![[WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
// CHECK: ![[INTERLEAVE_2]] = !{!"llvm.loop.interleave.count", i32 2}
-// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[WIDTH_1:.*]], ![[UNROLL_DISABLE:.*]]}
+// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[WIDTH_1:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[WIDTH_5:.*]]}
diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp
index e70c3aa36597..a0ad80d7c98a 100644
--- a/test/CodeGenCXX/rtti-fundamental.cpp
+++ b/test/CodeGenCXX/rtti-fundamental.cpp
@@ -89,6 +89,16 @@ namespace __cxxabiv1 {
// CHECK: @_ZTIPy = constant
// CHECK: @_ZTIPKy = constant
+// __int128
+// CHECK: @_ZTIn = constant
+// CHECK: @_ZTIPn = constant
+// CHECK: @_ZTIPKn = constant
+
+// unsigned __int128
+// CHECK: @_ZTIo = constant
+// CHECK: @_ZTIPo = constant
+// CHECK: @_ZTIPKo = constant
+
// half
// CHECK: @_ZTIDh = constant
// CHECK: @_ZTIPDh = constant
diff --git a/test/CodeGenCXX/sections.cpp b/test/CodeGenCXX/sections.cpp
index bec2e2d3d706..c33871a97f56 100644
--- a/test/CodeGenCXX/sections.cpp
+++ b/test/CodeGenCXX/sections.cpp
@@ -31,6 +31,31 @@ int TEST1;
#pragma bss_seg(pop)
int TEST2;
+
+// Check "save-restore" of pragma stacks.
+struct Outer {
+ void f() {
+ #pragma bss_seg(push, ".bss3")
+ #pragma code_seg(push, ".my_code1")
+ #pragma const_seg(push, ".my_const1")
+ #pragma data_seg(push, ".data3")
+ struct Inner {
+ void g() {
+ #pragma bss_seg(push, ".bss4")
+ #pragma code_seg(push, ".my_code2")
+ #pragma const_seg(push, ".my_const2")
+ #pragma data_seg(push, ".data4")
+ }
+ };
+ }
+};
+
+void h2(void) {} // should be in ".my_code"
+int TEST3; // should be in ".bss1"
+int d2 = 1; // should be in ".data"
+extern const int b2; // should be in ".my_const"
+const int b2 = 1;
+
#pragma section("read_flag_section", read)
// Even though they are not declared const, these become constant since they are
// in a read-only section.
@@ -63,6 +88,9 @@ __declspec(allocate("short_section")) short short_var = 42;
//CHECK: @i = global i32 0
//CHECK: @TEST1 = global i32 0
//CHECK: @TEST2 = global i32 0, section ".bss1"
+//CHECK: @TEST3 = global i32 0, section ".bss1"
+//CHECK: @d2 = global i32 1, section ".data"
+//CHECK: @b2 = constant i32 1, section ".my_const"
//CHECK: @unreferenced = constant i32 0, section "read_flag_section"
//CHECK: @referenced = constant i32 42, section "read_flag_section"
//CHECK: @implicitly_read_write = global i32 42, section "no_section_attributes"
@@ -70,3 +98,4 @@ __declspec(allocate("short_section")) short short_var = 42;
//CHECK: @short_var = global i16 42, section "short_section"
//CHECK: define void @g()
//CHECK: define void @h() {{.*}} section ".my_code"
+//CHECK: define void @h2() {{.*}} section ".my_code"
diff --git a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
index f6f90986e149..4734c02bc52e 100644
--- a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
@@ -27,7 +27,7 @@ struct A {
};
// CHECK-LABEL: define void @_ZN5Test21AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [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, i32 0, i32 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*], [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, i32 0, i32 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*], [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, i32 0, i32 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*], [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, i32 0, i32 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*], [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, i32 0, i32 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*], [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, i32 0, i32 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*], [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, i32 0, i32 2) to i32 (...)**), i32 (...)***
A::~A()
{
}
diff --git a/test/CodeGenCXX/stack-reuse.cpp b/test/CodeGenCXX/stack-reuse.cpp
index 473a57cda27d..d6340ef2c10b 100644
--- a/test/CodeGenCXX/stack-reuse.cpp
+++ b/test/CodeGenCXX/stack-reuse.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -target armv7l-unknown-linux-gnueabihf -S %s -o - -emit-llvm -O1 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-unknown-linux-gnueabihf %s -o - -emit-llvm -O1 | FileCheck %s
// Stack should be reused when possible, no need to allocate two separate slots
// if they have disjoint lifetime.
@@ -21,7 +21,7 @@ struct Combiner {
S_large a, b;
Combiner(S_large);
- Combiner f();
+ Combiner f();
};
extern S_small foo_small();
diff --git a/test/CodeGenCXX/static-destructor.cpp b/test/CodeGenCXX/static-destructor.cpp
new file mode 100644
index 000000000000..0ea84f8da6fa
--- /dev/null
+++ b/test/CodeGenCXX/static-destructor.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=X86 %s
+// RUN: %clang_cc1 %s -triple=wasm32 -emit-llvm -o - | FileCheck --check-prefix=WASM %s
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin9 -emit-llvm -o - | FileCheck --check-prefix=ARM %s
+
+// Test that destructors are not passed directly to __cxa_atexit when their
+// signatures do not match the type of its first argument.
+// e.g. ARM and WebAssembly have destructors that return this instead of void.
+
+
+class Foo {
+ public:
+ ~Foo() {
+ }
+};
+
+Foo global;
+
+// X86 destructors have void return, and are registered directly with __cxa_atexit.
+// X86: define internal void @__cxx_global_var_init()
+// X86: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
+
+// ARM destructors return this, but can be registered directly with __cxa_atexit
+// because the calling conventions tolerate the mismatch.
+// ARM: define internal void @__cxx_global_var_init()
+// ARM: call i32 @__cxa_atexit(void (i8*)* bitcast (%class.Foo* (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
+
+// Wasm destructors return this, and use a wrapper function, which is registered
+// with __cxa_atexit.
+// WASM: define internal void @__cxx_global_var_init()
+// WASM: call i32 @__cxa_atexit(void (i8*)* @__cxx_global_array_dtor, i8* null, i8* @__dso_handle)
+
+// WASM: define internal void @__cxx_global_array_dtor(i8*)
+// WASM: %call = call %class.Foo* @_ZN3FooD1Ev(%class.Foo* @global)
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index 541f6416efd0..bb974948a059 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -26,7 +26,7 @@ void f() {
}
void g() {
- // CHECK: call noalias i8* @_Znwm(i64 1)
+ // CHECK: call i8* @_Znwm(i64 1)
// CHECK: call void @_ZN1AC1Ev(
static A& a = *new A;
}
diff --git a/test/CodeGenCXX/strict-vtable-pointers.cpp b/test/CodeGenCXX/strict-vtable-pointers.cpp
index ee3919149cab..33f63994d7c0 100644
--- a/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ b/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -166,13 +166,13 @@ struct DynamicDerivedMultiple;
// CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
-// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i64 0, i64 2) {{.*}} %[[THIS10]]
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 2) {{.*}} %[[THIS10]]
// CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
// CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
// CHECK-CTORS: %[[THIS12:.*]] = bitcast i8* %[[THIS_ADD]] to i32 (...)***
-// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i64 0, i64 6) {{.*}} %[[THIS12]]
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 6) {{.*}} %[[THIS12]]
// CHECK-CTORS-LABEL: }
struct DynamicFromStatic;
diff --git a/test/CodeGenCXX/type-metadata.cpp b/test/CodeGenCXX/type-metadata.cpp
new file mode 100644
index 000000000000..076b1fdf1808
--- /dev/null
+++ b/test/CodeGenCXX/type-metadata.cpp
@@ -0,0 +1,248 @@
+// Tests for the cfi-vcall feature:
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=NDIAG %s
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=MS --check-prefix=TT-MS --check-prefix=NDIAG %s
+
+// Tests for the whole-program-vtables feature:
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=MS --check-prefix=TT-MS %s
+
+// Tests for cfi + whole-program-vtables:
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=ITANIUM --check-prefix=TC-ITANIUM %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=MS --check-prefix=TC-MS %s
+
+// ITANIUM: @_ZTV1A = {{[^!]*}}, !type [[A16:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL16:![0-9]+]]
+
+// ITANIUM: @_ZTV1B = {{[^!]*}}, !type [[A32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32:![0-9]+]]
+// ITANIUM-SAME: !type [[B32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+
+// ITANIUM: @_ZTV1C = {{[^!]*}}, !type [[A32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[C32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+
+// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}type-metadata.cpp\00", align 1
+// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" }
+// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { i8, { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }* } { i8 0, { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 123, i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]] }
+
+// ITANIUM: @_ZTVN12_GLOBAL__N_11DE = {{[^!]*}}, !type [[A32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[B32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[C88:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL88:![0-9]+]]
+// ITANIUM-SAME: !type [[D32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+
+// ITANIUM: @_ZTCN12_GLOBAL__N_11DE0_1B = {{[^!]*}}, !type [[A32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[B32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+
+// ITANIUM: @_ZTCN12_GLOBAL__N_11DE8_1C = {{[^!]*}}, !type [[A64:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL64:![0-9]+]]
+// ITANIUM-SAME: !type [[C32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+
+// ITANIUM: @_ZTVZ3foovE2FA = {{[^!]*}}, !type [[A16]]
+// ITANIUM-DIAG-SAME: !type [[ALL16]]
+// ITANIUM-SAME: !type [[FA16:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL16]]
+
+// MS: comdat($"\01??_7A@@6B@"), !type [[A8:![0-9]+]]
+// MS: comdat($"\01??_7B@@6B0@@"), !type [[B8:![0-9]+]]
+// MS: comdat($"\01??_7B@@6BA@@@"), !type [[A8]]
+// MS: comdat($"\01??_7C@@6B@"), !type [[A8]]
+// MS: comdat($"\01??_7D@?A@@6BB@@@"), !type [[B8]], !type [[D8:![0-9]+]]
+// MS: comdat($"\01??_7D@?A@@6BA@@@"), !type [[A8]]
+// MS: comdat($"\01??_7FA@?1??foo@@YAXXZ@6B@"), !type [[A8]], !type [[FA8:![0-9]+]]
+
+struct A {
+ A();
+ virtual void f();
+};
+
+struct B : virtual A {
+ B();
+ virtual void g();
+ virtual void h();
+};
+
+struct C : virtual A {
+ C();
+};
+
+namespace {
+
+struct D : B, C {
+ D();
+ virtual void f();
+ virtual void h();
+};
+
+}
+
+A::A() {}
+B::B() {}
+C::C() {}
+D::D() {}
+
+void A::f() {
+}
+
+void B::g() {
+}
+
+void D::f() {
+}
+
+void D::h() {
+}
+
+// ITANIUM: define hidden void @_Z2afP1A
+// MS: define void @"\01?af@@YAXPEAUA@@@Z"
+void af(A *a) {
+ // TT-ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* [[VT:%[^ ]*]], metadata !"_ZTS1A")
+ // TT-MS: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* [[VT:%[^ ]*]], metadata !"?AUA@@")
+ // TC-ITANIUM: [[PAIR:%[^ ]*]] = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"_ZTS1A")
+ // TC-MS: [[PAIR:%[^ ]*]] = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUA@@")
+ // CFI-VT: [[P:%[^ ]*]] = extractvalue { i8*, i1 } [[PAIR]], 1
+ // DIAG-NEXT: [[VTVALID0:%[^ ]*]] = call i1 @llvm.type.test(i8* [[VT]], metadata !"all-vtables")
+ // VTABLE-OPT: call void @llvm.assume(i1 [[P]])
+ // CFI-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]]
+ // CFI-NEXT: {{^$}}
+
+ // CFI: [[TRAPBB]]
+ // NDIAG-NEXT: call void @llvm.trap()
+ // NDIAG-NEXT: unreachable
+ // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64
+ // DIAG-NEXT: [[VTVALID:%[^ ]*]] = zext i1 [[VTVALID0]] to i64
+ // DIAG-ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
+ // DIAG-ABORT-NEXT: unreachable
+ // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
+ // DIAG-RECOVER-NEXT: br label %[[CONTBB]]
+
+ // CFI: [[CONTBB]]
+ // CFI-NVT: [[PTR:%[^ ]*]] = load
+ // CFI-VT: [[PTRI8:%[^ ]*]] = extractvalue { i8*, i1 } [[PAIR]], 0
+ // CFI-VT: [[PTR:%[^ ]*]] = bitcast i8* [[PTRI8]] to
+ // CFI: call void [[PTR]]
+#line 123
+ a->f();
+}
+
+// ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE
+// MS: define internal void @"\01?df1@@YAXPEAUD@?A@@@Z"
+void df1(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUA@@")
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata ![[DTYPE:[0-9]+]])
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUA@@")
+ d->f();
+}
+
+// ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE
+// MS: define internal void @"\01?dg1@@YAXPEAUD@?A@@@Z"
+void dg1(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUB@@")
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 8, metadata !"_ZTS1B")
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUB@@")
+ d->g();
+}
+
+// ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE
+// MS: define internal void @"\01?dh1@@YAXPEAUD@?A@@@Z"
+void dh1(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE]])
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 16, metadata ![[DTYPE]])
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 8, metadata ![[DTYPE:[0-9]+]])
+ d->h();
+}
+
+// ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE
+// MS: define internal void @"\01?df2@@YAXPEAUD@?A@@@Z"
+__attribute__((no_sanitize("cfi")))
+void df2(D *d) {
+ // CFI-NVT-NOT: call i1 @llvm.type.test
+ // CFI-VT: [[P:%[^ ]*]] = call i1 @llvm.type.test
+ // CFI-VT: call void @llvm.assume(i1 [[P]])
+ d->f();
+}
+
+// ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE
+// MS: define internal void @"\01?df3@@YAXPEAUD@?A@@@Z"
+__attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall")))
+void df3(D *d) {
+ // CFI-NVT-NOT: call i1 @llvm.type.test
+ // CFI-VT: [[P:%[^ ]*]] = call i1 @llvm.type.test
+ // CFI-VT: call void @llvm.assume(i1 [[P]])
+ d->f();
+}
+
+D d;
+
+void foo() {
+ df1(&d);
+ dg1(&d);
+ dh1(&d);
+ df2(&d);
+ df3(&d);
+
+ struct FA : A {
+ void f() {}
+ } fa;
+ af(&fa);
+}
+
+namespace test2 {
+
+struct A {
+ virtual void m_fn1();
+};
+struct B {
+ virtual void m_fn2();
+};
+struct C : B, A {};
+struct D : C {
+ void m_fn1();
+};
+
+// ITANIUM: define hidden void @_ZN5test21fEPNS_1DE
+// MS: define void @"\01?f@test2@@YAXPEAUD@1@@Z"
+void f(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTSN5test21DE")
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUA@test2@@")
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 8, metadata !"_ZTSN5test21DE")
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUA@test2@@")
+ d->m_fn1();
+}
+
+}
+
+// ITANIUM: [[A16]] = !{i64 16, !"_ZTS1A"}
+// ITANIUM-DIAG: [[ALL16]] = !{i64 16, !"all-vtables"}
+// ITANIUM: [[A32]] = !{i64 32, !"_ZTS1A"}
+// ITANIUM-DIAG: [[ALL32]] = !{i64 32, !"all-vtables"}
+// ITANIUM: [[B32]] = !{i64 32, !"_ZTS1B"}
+// ITANIUM: [[C32]] = !{i64 32, !"_ZTS1C"}
+// ITANIUM: [[C88]] = !{i64 88, !"_ZTS1C"}
+// ITANIUM-DIAG: [[ALL88]] = !{i64 88, !"all-vtables"}
+// ITANIUM: [[D32]] = !{i64 32, [[D_ID:![0-9]+]]}
+// ITANIUM: [[D_ID]] = distinct !{}
+// ITANIUM: [[A64]] = !{i64 64, !"_ZTS1A"}
+// ITANIUM-DIAG: [[ALL64]] = !{i64 64, !"all-vtables"}
+// ITANIUM: [[FA16]] = !{i64 16, [[FA_ID:![0-9]+]]}
+// ITANIUM: [[FA_ID]] = distinct !{}
+
+// MS: [[A8]] = !{i64 8, !"?AUA@@"}
+// MS: [[B8]] = !{i64 8, !"?AUB@@"}
+// MS: [[D8]] = !{i64 8, [[D_ID:![0-9]+]]}
+// MS: [[D_ID]] = distinct !{}
+// MS: [[FA8]] = !{i64 8, [[FA_ID:![0-9]+]]}
+// MS: [[FA_ID]] = distinct !{}
diff --git a/test/CodeGenCXX/virtual-base-ctor.cpp b/test/CodeGenCXX/virtual-base-ctor.cpp
index 20a88cd37105..8c8c310421dc 100644
--- a/test/CodeGenCXX/virtual-base-ctor.cpp
+++ b/test/CodeGenCXX/virtual-base-ctor.cpp
@@ -8,4 +8,4 @@ struct A { int a; A() { y = ((size_t)this - (size_t)&x) / sizeof(void*); } };
struct B : virtual A { void* x; };
B x;
-// CHECK: @y = global i8 2
+// CHECK: @y = local_unnamed_addr global i8 2
diff --git a/test/CodeGenCXX/virtual-function-attrs.cpp b/test/CodeGenCXX/virtual-function-attrs.cpp
new file mode 100644
index 000000000000..3a9a1a28ddf4
--- /dev/null
+++ b/test/CodeGenCXX/virtual-function-attrs.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
+
+class A {
+ virtual void f();
+ virtual void g();
+ virtual ~A();
+};
+
+void A::f() {}
+
+// CHECK: define [[CC:(x86_thiscallcc )?]]void @_ZN1A1fEv({{.*}}) unnamed_addr
+// CHECK: declare [[CC]]void @_ZN1A1gEv({{.*}}) unnamed_addr
+// CHECK: declare {{.*}} @_ZN1AD1Ev({{.*}}) unnamed_addr
+// CHECK: declare [[CC]]void @_ZN1AD0Ev({{.*}}) unnamed_addr
diff --git a/test/CodeGenCXX/vla-consruct.cpp b/test/CodeGenCXX/vla-consruct.cpp
new file mode 100644
index 000000000000..fd8314a5d716
--- /dev/null
+++ b/test/CodeGenCXX/vla-consruct.cpp
@@ -0,0 +1,139 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -O0 %s -emit-llvm -o - | FileCheck %s
+
+extern "C" int printf(const char *, ...);
+
+static int N;
+struct S {
+ S()
+ __attribute__((nothrow)) { printf("%d: S()\n", ++N); }
+ ~S() __attribute__((nothrow)) { printf("%d: ~S()\n", N--); }
+ int n[17];
+};
+// CHECK: [[struct_S:%.+]] = type { [17 x i32] }
+void print(int n, int a, int b, int c, int d) {
+ printf("n=%d\n,sizeof(S)=%d\nsizeof(array_t[0][0])=%d\nsizeof(array_t[0])=%d\nsizeof(array_t)=%d\n",
+ n, a, b, c, d);
+ if (n == 2)
+ throw(n);
+}
+
+void test(int n) {
+ // CHECK: define void {{.*test.*}}(i32 [[n:%.+]]) #
+ // CHECK: [[n_addr:%.+]] = alloca
+ // CHECK-NEXT: [[saved_stack:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_S:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_array_t_0_0:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_array_t_0:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_array_t:%.+]] = alloca
+ // CHECK-NEXT: [[exn_slot:%.+]] = alloca i8*
+ // CHECK-NEXT: [[ehselector_slot:%.+]] = alloca i32
+ // CHECK-NEXT: store i32 [[n]], i32* [[n_addr]]
+ // CHECK-NEXT: [[t0:%.+]] = load i32, i32* [[n_addr]]
+ // CHECK-NEXT: [[t1:%.+]] = zext i32 [[t0]] to i64
+ // CHECK-NEXT: [[t2:%.+]] = load i32, i32* [[n_addr]]
+ // CHECK-NEXT: [[add:%.+]] = add nsw i32 [[t2]], 1
+ // CHECK-NEXT: [[t3:%.+]] = zext i32 [[add]] to i64
+ // CHECK-NEXT: [[t4:%.+]] = call i8* @llvm.stacksave()
+ // CHECK-NEXT: store i8* [[t4]], i8** [[saved_stack]]
+ // CHECK-NEXT: [[t5:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[vla:%.+]] = alloca [[struct_S]], i64 [[t5]]
+ // CHECK-NEXT: [[t6:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[isempty:%.+]] = icmp eq i64 [[t6]], 0
+ // CHECK-NEXT: br i1 [[isempty]], label %[[arrayctor_cont:.+]], label %[[new_ctorloop:.+]]
+
+ S array_t[n][n + 1];
+
+ // CHECK: [[new_ctorloop]]
+ // CHECK-NEXT: [[arrayctor_end:%.+]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[vla]], i64 [[t6]]
+ // CHECK-NEXT: br label %[[arrayctor_loop:.+]]
+
+ // CHECK: [[arrayctor_loop]]
+ // CHECK-NEXT: [[arrayctor_cur:%.+]] = phi [[struct_S]]* [ [[vla]], %[[new_ctorloop]] ], [ [[arrayctor_next:%.+]], %[[arrayctor_loop]] ]
+ // CHECK-NEXT: call void [[ctor:@.+]]([[struct_S]]* [[arrayctor_cur]])
+ // CHECK-NEXT: [[arrayctor_next]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[arrayctor_cur]], i64 1
+ // CHECK-NEXT: [[arrayctor_done:%.+]] = icmp eq [[struct_S]]* [[arrayctor_next]], [[arrayctor_end]]
+ // CHECK-NEXT: br i1 [[arrayctor_done]], label %[[arrayctor_cont]], label %[[arrayctor_loop]]
+
+ int sizeof_S = sizeof(S);
+ int sizeof_array_t_0_0 = sizeof(array_t[0][0]);
+ int sizeof_array_t_0 = sizeof(array_t[0]);
+ int sizeof_array_t = sizeof(array_t);
+ print(n, sizeof_S, sizeof_array_t_0_0, sizeof_array_t_0, sizeof_array_t);
+
+ // CHECK: [[arrayctor_cont]]
+ // CHECK-NEXT: store i32 68, i32* [[sizeof_S]]
+ // CHECK-NEXT: store i32 68, i32* [[sizeof_array_t_0_0]]
+ // CHECK: [[t8:%.+]] = mul nuw i64 68, [[t3]]
+ // CHECK-NEXT: [[conv:%.+]] = trunc i64 [[t8]] to i32
+ // CHECK-NEXT: store i32 [[conv]], i32* [[sizeof_array_t_0]]
+ // CHECK-NEXT: [[t9:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[t10:%.+]] = mul nuw i64 68, [[t9]]
+ // CHECK-NEXT: [[conv1:%.+]] = trunc i64 [[t10]] to i32
+ // CHECK-NEXT: store i32 [[conv1]], i32* [[sizeof_array_t]]
+ // CHECK-NEXT: [[t11:%.+]] = load i32, i32* [[n_addr:%.+]]
+ // CHECK-NEXT: [[t12:%.+]] = load i32, i32* [[sizeof_S]]
+ // CHECK-NEXT: [[t13:%.+]] = load i32, i32* [[sizeof_array_t_0_0]]
+ // CHECK-NEXT: [[t14:%.+]] = load i32, i32* [[sizeof_array_t_0]]
+ // CHECK-NEXT: [[t15:%.+]] = load i32, i32* [[sizeof_array_t]]
+ // CHECK-NEXT: invoke void @{{.*print.*}}(i32 [[t11]], i32 [[t12]], i32 [[t13]], i32 [[t14]], i32 [[t15]])
+ // CHECK-NEXT: to label %[[invoke_cont:.+]] unwind label %[[lpad:.+]]
+
+ // CHECK: [[invoke_cont]]
+ // CHECK-NEXT: [[t16:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[t17:%.+]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[vla]], i64 [[t16]]
+ // CHECK-NEXT: [[arraydestroy_isempty:%.+]] = icmp eq [[struct_S]]* [[vla]], [[t17]]
+ // CHECK-NEXT: br i1 [[arraydestroy_isempty]], label %[[arraydestroy_done2:.+]], label %[[arraydestroy_body:.+]]
+
+ // CHECK: [[arraydestroy_body]]
+ // CHECK-NEXT: [[arraydestroy_elementPast:%.+]] = phi [[struct_S]]* [ [[t17]], %[[invoke_cont]] ], [ [[arraydestroy_element:%.+]], %[[arraydestroy_body]] ]
+ // CHECK-NEXT: [[arraydestroy_element]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[arraydestroy_elementPast]]
+ // CHECK-NEXT: call void @[[dtor:.+]]([[struct_S]]* [[arraydestroy_element]])
+ // CHECK-NEXT: [[arraydestroy_done:%.+]] = icmp eq [[struct_S]]* [[arraydestroy_element]], [[vla]]
+ // CHECK-NEXT: br i1 [[arraydestroy_done]], label %[[arraydestroy_done2]], label %[[arraydestroy_body]]
+
+ // CHECK: [[arraydestroy_done2]]
+ // CHECK-NEXT: [[t17:%.+]] = load i8*, i8** [[saved_stack]]
+ // CHECK-NEXT: call void @llvm.stackrestore(i8* [[t17]])
+ // CHECK: ret void
+
+ // CHECK: [[lpad]]
+ // CHECK-NEXT: [[t19:%.+]] = landingpad { i8*, i32 }
+ // CHECK: [[t20:%.+]] = extractvalue { i8*, i32 } [[t19]], 0
+ // CHECK-NEXT: store i8* [[t20]], i8** [[exn_slot]]
+ // CHECK-NEXT: [[t21:%.+]] = extractvalue { i8*, i32 } [[t19]], 1
+ // CHECK-NEXT: store i32 [[t21]], i32* [[ehselector_slot]]
+ // CHECK-NEXT: [[t22:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[t23:%.+]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[vla]], i64 [[t22]]
+ // CHECK-NEXT: [[arraydestroy_isempty3:%.+]] = icmp eq [[struct_S]]* [[vla]], [[t23]]
+ // CHECK-NEXT: br i1 [[arraydestroy_isempty3]], label %[[arraydestroy_done8:.+]], label %[[arraydestroy_body4:.+]]
+
+ // CHECK: [[arraydestroy_body4]]
+ // CHECK: [[arraydestroy_elementPast5:%.+]] = phi [[struct_S]]* [ [[t23]], %[[lpad]] ], [ [[arraydestroy_element6:.+]], %[[arraydestroy_body4]] ]
+ // CHECK-NEXT: [[arraydestroy_element6]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[arraydestroy_elementPast5]], i64 -1
+ // CHECK-NEXT: call void @[[dtor]]([[struct_S]]* [[arraydestroy_element6]])
+ // CHECK-NEXT: [[arraydestroy_done7:%.+]] = icmp eq [[struct_S]]* [[arraydestroy_element6]], [[vla]]
+ // CHECK-NEXT: br i1 [[arraydestroy_done7]], label %[[arraydestroy_done8]], label %[[arraydestroy_body4]]
+
+ // CHECK: [[arraydestroy_done8]]
+ // CHECK-NEXT: br label %[[eh_resume:.+]]
+
+ // CHECK: [[eh_resume]]
+ // CHECK-NEXT: [[exn:%.+]] = load i8*, i8** [[exn_slot]]
+ // CHECK-NEXT: [[sel:%.+]] = load i32, i32* [[ehselector_slot]]
+ // CHECK-NEXT: [[lpad_val:%.+]] = insertvalue { i8*, i32 } undef, i8* [[exn]], 0
+ // CHECK-NEXT: [[lpad_val9:%.+]] = insertvalue { i8*, i32 } [[lpad_val]], i32 [[sel]], 1
+ // CHECK-NEXT: resume { i8*, i32 } [[lpad_val9]]
+}
+
+int main() {
+ try {
+ test(2);
+ } catch (int e) {
+ printf("expeption %d\n", e);
+ }
+ try {
+ test(3);
+ } catch (int e) {
+ printf("expeption %d", e);
+ }
+}
diff --git a/test/CodeGenCXX/vtable-assume-load.cpp b/test/CodeGenCXX/vtable-assume-load.cpp
index 30cfc00ec7ba..819b09d70e3d 100644
--- a/test/CodeGenCXX/vtable-assume-load.cpp
+++ b/test/CodeGenCXX/vtable-assume-load.cpp
@@ -27,7 +27,7 @@ void g(A *a) { a->foo(); }
// CHECK1-LABEL: define void @_ZN5test14fooAEv()
// CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"*
// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
-// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i32 0, i32 2)
// CHECK1: call void @llvm.assume(i1 %[[CMP]])
// CHECK1-LABEL: }
@@ -39,7 +39,7 @@ void fooA() {
// CHECK1-LABEL: define void @_ZN5test14fooBEv()
// CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}})
// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
-// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i32 0, i32 2)
// CHECK1: call void @llvm.assume(i1 %[[CMP]])
// CHECK1-LABEL: }
@@ -73,14 +73,14 @@ void h(B *b) { b->bar(); }
// CHECK2-LABEL: define void @_ZN5test24testEv()
// CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"*
// CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}}
-// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 2)
+// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i32 0, i32 2)
// CHECK2: call void @llvm.assume(i1 %[[CMP]])
// CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8*
// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8
// CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8***
// CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]]
-// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 5)
+// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i32 0, i32 5)
// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
// CHECK2: call void @_ZN5test21gEPNS_1AE(
@@ -111,7 +111,7 @@ void g(B *a) { a->foo(); }
// CHECK3-LABEL: define void @_ZN5test34testEv()
// CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"*
-// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5test31CE, i64 0, i64 3)
+// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5test31CE, i32 0, i32 3)
// CHECK3: call void @llvm.assume(i1 %[[CMP]])
// CHECK3-LABLEL: }
void test() {
@@ -140,11 +140,11 @@ void g(C *c) { c->foo(); }
// CHECK4-LABEL: define void @_ZN5test44testEv()
// CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"*
// CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
-// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)
+// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i32 0, i32 4)
// CHECK4: call void @llvm.assume(i1 %[[CMP]]
// CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}}
-// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)
+// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i32 0, i32 4)
// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
// CHECK4-LABEL: }
diff --git a/test/CodeGenCXX/vtable-key-function-arm.cpp b/test/CodeGenCXX/vtable-key-function-arm.cpp
index 6f1265b6277d..3d5c3c3865ea 100644
--- a/test/CodeGenCXX/vtable-key-function-arm.cpp
+++ b/test/CodeGenCXX/vtable-key-function-arm.cpp
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
-// The 'a' variants ask for the v-table first.
-// The 'b' variants ask for the v-table second.
-// The 'c' variants ask for the v-table third.
+// The 'a' variants ask for the vtable first.
+// The 'b' variants ask for the vtable second.
+// The 'c' variants ask for the vtable third.
// We do a separate CHECK-LATE pass because the RTTI definition gets
// changed after the fact, which causes reordering of the globals.
diff --git a/test/CodeGenCXX/vtable-key-function-ios.cpp b/test/CodeGenCXX/vtable-key-function-ios.cpp
index d17aa695d2b5..8a3466beda44 100644
--- a/test/CodeGenCXX/vtable-key-function-ios.cpp
+++ b/test/CodeGenCXX/vtable-key-function-ios.cpp
@@ -4,9 +4,9 @@
// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
-// The 'a' variants ask for the v-table first.
-// The 'b' variants ask for the v-table second.
-// The 'c' variants ask for the v-table third.
+// The 'a' variants ask for the vtable first.
+// The 'b' variants ask for the vtable second.
+// The 'c' variants ask for the vtable third.
// We do a separate CHECK-LATE pass because the RTTI definition gets
// changed after the fact, which causes reordering of the globals.
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index ff398ffa61dd..0b556d10c3e8 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -1,6 +1,6 @@
// 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 %s < %t
// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
namespace {
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index 2854291e2965..130a55cf6218 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*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 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*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i32 0, i32 2) to i32 (...)**)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
// CHECK: ret void
@@ -49,12 +49,12 @@ void f() { B b; }
// 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*], [3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i32 0, i32 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: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i32 0, i32 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 2f441ff7e18a..7ff93dd451c9 100644
--- a/test/CodeGenCXX/vtt-layout.cpp
+++ b/test/CodeGenCXX/vtt-layout.cpp
@@ -78,9 +78,11 @@ namespace Test6 {
}
}
-// 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: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5Test11BE, i32 0, i32 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: @_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*)]
+// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5Test21CE, i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5Test21CE, i32 0, i32 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, i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i32 0, i32 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 1, i32 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 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, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i32 0, i32 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 1, i32 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 10) to i8*)]
+// CHECK: declare void @__cxa_pure_virtual() unnamed_addr
+// CHECK: declare void @__cxa_deleted_virtual() unnamed_addr