aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
commitbab175ec4b075c8076ba14c762900392533f6ee4 (patch)
tree01f4f29419a2cb10abe13c1e63cd2a66068b0137 /test/CodeGenCXX
parent8b7a8012d223fac5d17d16a66bb39168a9a1dfc0 (diff)
Notes
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/PR26569.cpp16
-rw-r--r--test/CodeGenCXX/alias-available-externally.cpp20
-rw-r--r--test/CodeGenCXX/alloc-size.cpp72
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-call-2.cpp16
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-call.cpp6
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp8
-rw-r--r--test/CodeGenCXX/arm-swiftcall.cpp2
-rw-r--r--test/CodeGenCXX/arm64.cpp36
-rw-r--r--test/CodeGenCXX/atomicinit.cpp4
-rw-r--r--test/CodeGenCXX/attr.cpp2
-rw-r--r--test/CodeGenCXX/block-in-ctor-dtor.cpp2
-rw-r--r--test/CodeGenCXX/builtins-arm-exclusive.cpp24
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp8
-rw-r--r--test/CodeGenCXX/cfi-cross-dso.cpp2
-rw-r--r--test/CodeGenCXX/compound-literals.cpp40
-rw-r--r--test/CodeGenCXX/const-init-cxx11.cpp6
-rw-r--r--test/CodeGenCXX/constructor-destructor-return-this.cpp2
-rw-r--r--test/CodeGenCXX/constructor-init.cpp17
-rw-r--r--test/CodeGenCXX/copy-constructor-elim-2.cpp20
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis-2.cpp2
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis.cpp2
-rw-r--r--test/CodeGenCXX/ctor-dtor-alias.cpp6
-rw-r--r--test/CodeGenCXX/cxx11-exception-spec.cpp2
-rw-r--r--test/CodeGenCXX/cxx11-noreturn.cpp2
-rw-r--r--test/CodeGenCXX/cxx1y-initializer-aggregate.cpp2
-rw-r--r--test/CodeGenCXX/cxx1y-variable-template-linkage.cpp4
-rw-r--r--test/CodeGenCXX/cxx1z-aligned-allocation.cpp206
-rw-r--r--test/CodeGenCXX/cxx1z-constexpr-if.cpp13
-rw-r--r--test/CodeGenCXX/cxx1z-copy-omission.cpp81
-rw-r--r--test/CodeGenCXX/cxx1z-decomposition.cpp118
-rw-r--r--test/CodeGenCXX/cxx1z-eval-order.cpp271
-rw-r--r--test/CodeGenCXX/cxx1z-noexcept-function-type.cpp9
-rw-r--r--test/CodeGenCXX/debug-info-access.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-alias.cpp5
-rw-r--r--test/CodeGenCXX/debug-info-anon-namespace.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-anon-union-vars.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-calling-conventions.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-class-nolimit.cpp24
-rw-r--r--test/CodeGenCXX/debug-info-class.cpp1
-rw-r--r--test/CodeGenCXX/debug-info-codeview-injected-class.cpp21
-rw-r--r--test/CodeGenCXX/debug-info-cxx1y.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-dllimport-base-class.cpp53
-rw-r--r--test/CodeGenCXX/debug-info-dup-fwd-decl.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-enum-class.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-flex-member.cpp9
-rw-r--r--test/CodeGenCXX/debug-info-global.cpp5
-rw-r--r--test/CodeGenCXX/debug-info-indirect-field-decl.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-line-if.cpp20
-rw-r--r--test/CodeGenCXX/debug-info-line.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-loops.cpp49
-rw-r--r--test/CodeGenCXX/debug-info-method.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-ms-abi.cpp24
-rw-r--r--test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-ms-bitfields.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp7
-rw-r--r--test/CodeGenCXX/debug-info-ms-vbase.cpp68
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp17
-rw-r--r--test/CodeGenCXX/debug-info-rvalue-ref.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-static-member.cpp32
-rw-r--r--test/CodeGenCXX/debug-info-template-explicit-specialization.cpp7
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp10
-rw-r--r--test/CodeGenCXX/debug-info-template-quals.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-template.cpp30
-rw-r--r--test/CodeGenCXX/debug-info-thunk-msabi.cpp19
-rw-r--r--test/CodeGenCXX/debug-info-thunk.cpp13
-rw-r--r--test/CodeGenCXX/debug-info-union.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-uuid.cpp29
-rw-r--r--test/CodeGenCXX/debug-info-vla.cpp20
-rw-r--r--test/CodeGenCXX/debug-info-windows-dtor.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-zero-length-arrays.cpp1
-rw-r--r--test/CodeGenCXX/debug-info.cpp12
-rw-r--r--test/CodeGenCXX/debug-lambda-expressions.cpp10
-rw-r--r--test/CodeGenCXX/debug-lambda-this.cpp4
-rw-r--r--test/CodeGenCXX/default-arg-temps.cpp9
-rw-r--r--test/CodeGenCXX/derived-to-base.cpp2
-rw-r--r--test/CodeGenCXX/destructors.cpp128
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp16
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls.cpp97
-rw-r--r--test/CodeGenCXX/dllexport.cpp17
-rw-r--r--test/CodeGenCXX/dllimport-members.cpp2
-rw-r--r--test/CodeGenCXX/dllimport-rtti.cpp8
-rw-r--r--test/CodeGenCXX/dllimport.cpp27
-rw-r--r--test/CodeGenCXX/empty-classes.cpp21
-rw-r--r--test/CodeGenCXX/enable_if.cpp2
-rw-r--r--test/CodeGenCXX/exceptions-seh.cpp2
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp2
-rw-r--r--test/CodeGenCXX/global-dtor-no-atexit.cpp2
-rw-r--r--test/CodeGenCXX/global-init.cpp9
-rw-r--r--test/CodeGenCXX/implicit-copy-constructor.cpp8
-rw-r--r--test/CodeGenCXX/init-invariant.cpp14
-rw-r--r--test/CodeGenCXX/inline-dllexport-member.cpp8
-rw-r--r--test/CodeGenCXX/inline-hint.cpp6
-rw-r--r--test/CodeGenCXX/invariant.group-for-vptrs.cpp6
-rw-r--r--test/CodeGenCXX/key-function-vtable.cpp10
-rw-r--r--test/CodeGenCXX/lambda-expressions.cpp78
-rw-r--r--test/CodeGenCXX/linkage.cpp2
-rw-r--r--test/CodeGenCXX/main-norecurse.cpp2
-rw-r--r--test/CodeGenCXX/mangle-abi-tag.cpp29
-rw-r--r--test/CodeGenCXX/mangle-exception-spec.cpp49
-rw-r--r--test/CodeGenCXX/mangle-lambdas.cpp10
-rw-r--r--test/CodeGenCXX/mangle-ms-cxx11.cpp29
-rw-r--r--test/CodeGenCXX/mangle-unnamed.cpp3
-rw-r--r--test/CodeGenCXX/mangle.cpp14
-rw-r--r--test/CodeGenCXX/microsoft-abi-array-cookies.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-catch.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp37
-rw-r--r--test/CodeGenCXX/microsoft-abi-extern-template.cpp6
-rw-r--r--test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp12
-rw-r--r--test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp48
-rw-r--r--test/CodeGenCXX/microsoft-abi-structors-alias.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-structors.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-vftables.cpp34
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp16
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp23
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp16
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp10
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp16
-rw-r--r--test/CodeGenCXX/microsoft-interface.cpp6
-rw-r--r--test/CodeGenCXX/microsoft-no-rtti-data.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-uuidof.cpp8
-rw-r--r--test/CodeGenCXX/modules-ts.cppm20
-rw-r--r--test/CodeGenCXX/ms-inline-asm-return.cpp10
-rw-r--r--test/CodeGenCXX/ms-thread_local.cpp5
-rw-r--r--test/CodeGenCXX/naked.cpp13
-rw-r--r--test/CodeGenCXX/new-array-init.cpp84
-rw-r--r--test/CodeGenCXX/no-exceptions.cpp2
-rw-r--r--test/CodeGenCXX/nrvo.cpp28
-rw-r--r--test/CodeGenCXX/optnone-class-members.cpp2
-rw-r--r--test/CodeGenCXX/optnone-def-decl.cpp2
-rw-r--r--test/CodeGenCXX/partial-destruction.cpp39
-rw-r--r--test/CodeGenCXX/pr24097.cpp2
-rw-r--r--test/CodeGenCXX/pr30731.cpp21
-rw-r--r--test/CodeGenCXX/pragma-loop-distribute.cpp23
-rw-r--r--test/CodeGenCXX/pragma-loop-safety.cpp24
-rw-r--r--test/CodeGenCXX/predefined-expr-cxx14.cpp4
-rw-r--r--test/CodeGenCXX/reference-cast.cpp2
-rw-r--r--test/CodeGenCXX/regcall.cpp97
-rw-r--r--test/CodeGenCXX/rtti-mingw64.cpp13
-rw-r--r--test/CodeGenCXX/rtti-qualfn.cpp23
-rw-r--r--test/CodeGenCXX/runtime-dllstorage.cpp158
-rw-r--r--test/CodeGenCXX/sanitize-dtor-bit-field.cpp4
-rw-r--r--test/CodeGenCXX/sanitize-dtor-derived-class.cpp4
-rw-r--r--test/CodeGenCXX/sanitize-dtor-tail-call.cpp4
-rw-r--r--test/CodeGenCXX/sanitize-dtor-trivial.cpp4
-rw-r--r--test/CodeGenCXX/sanitize-dtor-vtable.cpp4
-rw-r--r--test/CodeGenCXX/skip-vtable-pointer-initialization.cpp16
-rw-r--r--test/CodeGenCXX/stack-reuse-miscompile.cpp2
-rw-r--r--test/CodeGenCXX/stack-reuse.cpp2
-rw-r--r--test/CodeGenCXX/strict-vtable-pointers.cpp36
-rw-r--r--test/CodeGenCXX/template-instantiation.cpp2
-rw-r--r--test/CodeGenCXX/temporaries.cpp30
-rw-r--r--test/CodeGenCXX/threadsafe-statics.cpp4
-rw-r--r--test/CodeGenCXX/thunks.cpp11
-rw-r--r--test/CodeGenCXX/ubsan-devirtualized-calls.cpp81
-rw-r--r--test/CodeGenCXX/ubsan-vtable-checks.cpp40
-rw-r--r--test/CodeGenCXX/uncopyable-args.cpp74
-rw-r--r--test/CodeGenCXX/value-init.cpp10
-rw-r--r--test/CodeGenCXX/virtual-base-cast.cpp2
-rw-r--r--test/CodeGenCXX/virtual-destructor-calls.cpp2
-rw-r--r--test/CodeGenCXX/virtual-function-calls.cpp7
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp2
-rw-r--r--test/CodeGenCXX/vla-lambda-capturing.cpp4
-rw-r--r--test/CodeGenCXX/vtable-align.cpp4
-rw-r--r--test/CodeGenCXX/vtable-assume-load.cpp42
-rw-r--r--test/CodeGenCXX/vtable-available-externally.cpp2
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp2
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp11
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp8
-rw-r--r--test/CodeGenCXX/vtt-layout.cpp13
-rw-r--r--test/CodeGenCXX/wasm-args-returns.cpp4
-rw-r--r--test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp18
-rw-r--r--test/CodeGenCXX/windows-itanium-dllexport.cpp30
-rw-r--r--test/CodeGenCXX/windows-itanium-type-info.cpp40
174 files changed, 2996 insertions, 516 deletions
diff --git a/test/CodeGenCXX/PR26569.cpp b/test/CodeGenCXX/PR26569.cpp
index 3e2d2ffeba14..859b6e26f0c4 100644
--- a/test/CodeGenCXX/PR26569.cpp
+++ b/test/CodeGenCXX/PR26569.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-optzns %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-passes %s -o - | FileCheck %s
-class A {
+class __declspec(dllimport) A {
virtual void m_fn1();
};
template <typename>
@@ -9,12 +9,12 @@ 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: @[[VTABLE_C:.*]] = private unnamed_addr constant { [2 x i8*] } { [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*] } { [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*] } { [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??_SA@@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??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_C]], i32 0, 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 0, i32 1)
+// CHECK-DAG: @"\01??_SA@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_A]], i32 0, 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/alias-available-externally.cpp b/test/CodeGenCXX/alias-available-externally.cpp
new file mode 100644
index 000000000000..473e93be0a75
--- /dev/null
+++ b/test/CodeGenCXX/alias-available-externally.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -O1 -std=c++11 -emit-llvm -triple %itanium_abi_triple -disable-llvm-passes -o - %s | FileCheck %s
+// Clang should not generate alias to available_externally definitions.
+// Check that the destructor of Foo is defined.
+// The destructors have different return type for different targets.
+// CHECK: define linkonce_odr {{.*}} @_ZN3FooD2Ev
+template <class CharT>
+struct String {
+ String() {}
+ ~String();
+};
+
+template <class CharT>
+inline __attribute__((visibility("hidden"), always_inline))
+String<CharT>::~String() {}
+
+extern template struct String<char>;
+
+struct Foo : public String<char> { Foo() { String<char> s; } };
+
+Foo f;
diff --git a/test/CodeGenCXX/alloc-size.cpp b/test/CodeGenCXX/alloc-size.cpp
new file mode 100644
index 000000000000..e93e231b70e8
--- /dev/null
+++ b/test/CodeGenCXX/alloc-size.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s
+
+namespace templates {
+void *my_malloc(int N) __attribute__((alloc_size(1)));
+void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2)));
+
+struct MyType {
+ int arr[4];
+};
+
+template <typename T> int callMalloc();
+
+template <typename T, int N> int callCalloc();
+
+// CHECK-LABEL: define i32 @_ZN9templates6testItEv()
+int testIt() {
+ // CHECK: call i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv
+ // CHECK: call i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
+ return callMalloc<MyType>() + callCalloc<MyType, 4>();
+}
+
+// CHECK-LABEL: define linkonce_odr i32
+// @_ZN9templates10callMallocINS_6MyTypeEEEiv
+template <typename T> int callMalloc() {
+ static_assert(sizeof(T) == 16, "");
+ // CHECK: ret i32 16
+ return __builtin_object_size(my_malloc(sizeof(T)), 0);
+}
+
+// CHECK-LABEL: define linkonce_odr i32
+// @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
+template <typename T, int N> int callCalloc() {
+ static_assert(sizeof(T) * N == 64, "");
+ // CHECK: ret i32 64
+ return __builtin_object_size(my_malloc(sizeof(T) * N), 0);
+}
+}
+
+namespace templated_alloc_size {
+using size_t = unsigned long;
+
+// We don't need bodies for any of these, because they're only used in
+// __builtin_object_size, and that shouldn't need anything but a function
+// decl with alloc_size on it.
+template <typename T>
+T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1)));
+
+template <typename T>
+T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1)));
+
+template <size_t N>
+void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1)));
+
+template <size_t N, size_t M>
+void *dependent_calloc(size_t NT = N, size_t MT = M)
+ __attribute__((alloc_size(1, 2)));
+
+template <typename T, size_t M>
+void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M)
+ __attribute__((alloc_size(1, 2)));
+
+// CHECK-LABEL: define i32 @_ZN20templated_alloc_size6testItEv
+int testIt() {
+ // 122 = 4 + 5*4 + 6 + 7*8 + 4*9
+ // CHECK: ret i32 122
+ return __builtin_object_size(my_malloc<int>(), 0) +
+ __builtin_object_size(my_calloc<int>(5), 0) +
+ __builtin_object_size(dependent_malloc<6>(), 0) +
+ __builtin_object_size(dependent_calloc<7, 8>(), 0) +
+ __builtin_object_size(dependent_calloc2<int, 9>(), 0);
+}
+}
diff --git a/test/CodeGenCXX/apple-kext-indirect-call-2.cpp b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
index d441b78140e7..3b2cda8b583b 100644
--- a/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
+++ b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
-// CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null]
-// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null]
-// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null]
-// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null]
+// CHECK: @_ZTV1A = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null] }
+// CHECK: @_ZTV4Base = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null] }
+// CHECK: @_ZTV8Derived2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null] }
+// CHECK: @_ZTV2D2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null] }
struct A {
virtual const char* abc(void) const;
@@ -18,7 +18,7 @@ struct B : virtual A {
void B::VF() {}
void FUNC(B* p) {
-// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2)
+// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ({ [4 x i8*] }* @_ZTV1A to i8* (%struct.A*)**), i64 2)
// CHECK-NEXT: [[T2:%.*]] = call i8* [[T1]]
const char* c = p->A::abc();
}
@@ -33,7 +33,7 @@ struct Derived : public Base {
};
void FUNC1(Derived* p) {
-// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.Base*)**), i64 2)
+// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to i8* (%struct.Base*)**), i64 2)
// CHECK-NEXT: [[U2:%.*]] = call i8* [[U1]]
char* c = p->Base::abc();
}
@@ -49,7 +49,7 @@ struct Derived2 : virtual Base2 {
char* Derived2::efg(void) const { return 0; }
void FUNC2(Derived2* p) {
-// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3)
+// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ({ [5 x i8*] }* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3)
// CHECK-NEXT: [[V2:%.*]] = call i8* [[V1]]
char* c = p->Derived2::efg();
}
@@ -70,7 +70,7 @@ struct Sub : D1, D2 {
char* D2::abc(void) const { return 0; }
void FUNC3(Sub* p) {
-// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
+// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ({ [5 x i8*] }* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
// CHECK-NEXT: [[W2:%.*]] = call i8* [[W1]]
char* c = p->D2::abc();
}
diff --git a/test/CodeGenCXX/apple-kext-indirect-call.cpp b/test/CodeGenCXX/apple-kext-indirect-call.cpp
index e4c03b5da50b..ac0e3f4d39c6 100644
--- a/test/CodeGenCXX/apple-kext-indirect-call.cpp
+++ b/test/CodeGenCXX/apple-kext-indirect-call.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
-// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null]
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
struct Base {
virtual void abc(void) const;
@@ -12,7 +12,7 @@ void FUNC(Base* p) {
p->Base::abc();
}
-// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2)
+// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to void (%struct.Base*)**), i64 2)
// CHECK-NOT: call void @_ZNK4Base3abcEv
template<class T>
@@ -37,6 +37,6 @@ void f(SubTempl<int>* t) {
t->Templ::f();
}
-// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([5 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
+// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [5 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
diff --git a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
index 5f6bdb230fe7..4cfa88d99455 100644
--- a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
+++ b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
-// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null]
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x i8*] } { [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
struct B1 {
virtual ~B1();
@@ -12,10 +12,10 @@ void DELETE(B1 *pb1) {
pb1->B1::~B1();
}
// CHECK-LABEL: define void @_ZN2B1D0Ev
-// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]])
// CHECK-LABEL: define void @_Z6DELETEP2B1
-// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]])
template<class T>
@@ -42,7 +42,7 @@ void f(SubTempl<int>* t) {
t->Templ::~Templ();
}
-// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([7 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
+// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [7 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
// CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*)
// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
diff --git a/test/CodeGenCXX/arm-swiftcall.cpp b/test/CodeGenCXX/arm-swiftcall.cpp
index 535350c808d3..5c932c77b1da 100644
--- a/test/CodeGenCXX/arm-swiftcall.cpp
+++ b/test/CodeGenCXX/arm-swiftcall.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 | FileCheck %s -check-prefixes=CHECK
// This isn't really testing anything ARM-specific; it's just a convenient
// 32-bit platform.
diff --git a/test/CodeGenCXX/arm64.cpp b/test/CodeGenCXX/arm64.cpp
index 19f72726e690..80438397c3f2 100644
--- a/test/CodeGenCXX/arm64.cpp
+++ b/test/CodeGenCXX/arm64.cpp
@@ -84,3 +84,39 @@ namespace test2 {
// CHECK-GLOBALS-DAG: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
}
+
+// ARM64 reserves the top half of the vtable offset in virtual
+// member pointers.
+namespace test3 {
+ struct A {
+ virtual void foo();
+ virtual void bar();
+ };
+
+ // The offset half of the pointer is still initialized to zero.
+ // CHECK-GLOBALS-DAG: @_ZN5test34mptrE = global { i64, i64 } { i64 0, i64 1 }
+ void (A::*mptr)() = &A::foo;
+
+ // CHECK-LABEL: define void @_ZN5test34testEv()
+ // CHECK: [[TEMP:%.*]] = alloca [[A:.*]], align 8
+ // CHECK: [[MEMPTR:%.*]] = load { i64, i64 }, { i64, i64 }* @_ZN5test34mptrE, align 8
+ // CHECK: [[ADJUST_AND_IS_VIRTUAL:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 1
+ // CHECK: [[ADJUST:%.*]] = ashr i64 [[ADJUST_AND_IS_VIRTUAL]], 1
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[TEMP]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[ADJUST]]
+ // CHECK: [[ADJUSTED:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK: [[MEMBER:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 0
+ // CHECK: [[T0:%.*]] = and i64 [[ADJUST_AND_IS_VIRTUAL]], 1
+ // CHECK: [[IS_VIRTUAL:%.*]] = icmp ne i64 [[T0]], 0
+ // CHECK: br i1 [[IS_VIRTUAL]],
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[ADJUSTED]] to i8**
+ // CHECK: [[VPTR:%.*]] = load i8*, i8** [[T0]], align 8
+ // CHECK: [[TRUNC:%.*]] = trunc i64 [[MEMBER]] to i32
+ // CHECK: [[ZEXT:%.*]] = zext i32 [[TRUNC]] to i64
+ // CHECK: [[T0:%.*]] = getelementptr i8, i8* [[VPTR]], i64 [[ZEXT]]
+ // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to void ([[A]]*)**
+ // CHECK: load void ([[A]]*)*, void ([[A]]*)** [[T1]],
+ void test() {
+ (A().*mptr)();
+ }
+}
diff --git a/test/CodeGenCXX/atomicinit.cpp b/test/CodeGenCXX/atomicinit.cpp
index 96f44d52f286..4c30ec35212f 100644
--- a/test/CodeGenCXX/atomicinit.cpp
+++ b/test/CodeGenCXX/atomicinit.cpp
@@ -51,8 +51,8 @@ struct AtomicBoolMember {
};
// CHECK-LABEL: define void @_ZN16AtomicBoolMemberC2Eb
-// CHECK: {{zext i1.*to i8}}
-// CHECK-NEXT: store i8
+// CHECK: zext i1 {{.*}} to i8
+// CHECK: store i8
// CHECK-NEXT: ret void
AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { }
diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp
index 67993b4227a1..7f5595f6f044 100644
--- a/test/CodeGenCXX/attr.cpp
+++ b/test/CodeGenCXX/attr.cpp
@@ -31,4 +31,4 @@ int test1() { return 10; }
// CHECK at top of file
extern "C" int test2() __attribute__((alias("_Z5test1v")));
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
index 0dc0ab00437f..0ec9db1db728 100644
--- a/test/CodeGenCXX/block-in-ctor-dtor.cpp
+++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -42,7 +42,5 @@ X::~X() {
// CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke_
// CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke
// CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke_
-// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke
-// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke_
// CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke
// CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke_
diff --git a/test/CodeGenCXX/builtins-arm-exclusive.cpp b/test/CodeGenCXX/builtins-arm-exclusive.cpp
new file mode 100644
index 000000000000..06f7a023adec
--- /dev/null
+++ b/test/CodeGenCXX/builtins-arm-exclusive.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64
+
+bool b;
+
+// CHECK-LABEL: @_Z10test_ldrexv()
+// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* @b)
+
+// CHECK-ARM64-LABEL: @_Z10test_ldrexv()
+// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* @b)
+
+void test_ldrex() {
+ b = __builtin_arm_ldrex(&b);
+}
+
+// CHECK-LABEL: @_Z10tset_strexv()
+// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* @b)
+
+// CHECK-ARM64-LABEL: @_Z10tset_strexv()
+// CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* @b)
+
+void tset_strex() {
+ __builtin_arm_strex(true, &b);
+}
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 3ca7f6d65ad4..179c33412267 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -277,13 +277,13 @@ int array_index(const int (&a)[4], int n) {
int multi_array_index(int n, int m) {
int arr[4][6];
- // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6
- // CHECK: br i1 %[[IDX2_OK]]
- // CHECK: call void @__ubsan_handle_out_of_bounds(
-
// CHECK: %[[IDX1_OK:.*]] = icmp ult i64 %{{.*}}, 4
// CHECK: br i1 %[[IDX1_OK]]
// CHECK: call void @__ubsan_handle_out_of_bounds(
+
+ // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6
+ // CHECK: br i1 %[[IDX2_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
return arr[n][m];
}
diff --git a/test/CodeGenCXX/cfi-cross-dso.cpp b/test/CodeGenCXX/cfi-cross-dso.cpp
index d67927d4d2ed..bfa0705c6f8f 100644
--- a/test/CodeGenCXX/cfi-cross-dso.cpp
+++ b/test/CodeGenCXX/cfi-cross-dso.cpp
@@ -26,7 +26,7 @@ void g() {
b.f();
}
-// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant [2 x i8*] {{.*}}@"\01??_R4B@?A@@6B@"{{.*}}@"\01?f@B@?A@@UEAAXXZ"
+// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"\01??_R4B@?A@@6B@"{{.*}}@"\01?f@B@?A@@UEAAXXZ"
// CHECK: %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)***
// CHECK: %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize
diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp
index 69632a7de2f4..a9882bc6d241 100644
--- a/test/CodeGenCXX/compound-literals.cpp
+++ b/test/CodeGenCXX/compound-literals.cpp
@@ -12,6 +12,9 @@ struct Y {
X x;
};
+// CHECK: @.compoundliteral = internal global [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5], align 4
+// CHECK: @q = global i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral, i32 0, i32 0), align 4
+
// CHECK-LABEL: define i32 @_Z1fv()
int f() {
// CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca
@@ -38,20 +41,45 @@ int g() {
return v[0];
}
+// GCC's compound-literals-in-C++ extension lifetime-extends a compound literal
+// (or a C++11 list-initialized temporary!) if:
+// - it is at global scope
+// - it has array type
+// - it has a constant initializer
+
struct Z { int i[3]; };
int *p = (Z){ {1, 2, 3} }.i;
// CHECK: define {{.*}}__cxx_global_var_init()
-// CHECK: store i32* getelementptr inbounds (%struct.Z, %struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p
+// CHECK: alloca %struct.Z
+// CHECK: store i32* %{{.*}}, i32** @p
+int *q = (int [5]){1, 2, 3, 4, 5};
+// (constant initialization, checked above)
-int *PR21912_1 = (int []){};
+extern int n;
+int *r = (int [5]){1, 2, 3, 4, 5} + n;
// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1()
-// CHECK: store i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.2, i32 0, i32 0), i32** @PR21912_1
+// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral.2, i32 0, i32 0), i32 %
+// CHECK: store i32* %[[PTR]], i32** @r
+
+int *PR21912_1 = (int []){} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.4, i32 0, i32 0), i32 %
+// CHECK: store i32* %[[PTR]], i32** @PR21912_1
union PR21912Ty {
long long l;
double d;
};
-union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}};
-// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3()
-// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.4 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2
+union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.5()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds %union.PR21912Ty, %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.6 to [2 x %union.PR21912Ty]*), i32 0, i32 0), i32 %
+// CHECK: store %union.PR21912Ty* %[[PTR]], %union.PR21912Ty** @PR21912_2, align 4
+
+// This compound literal should have local scope.
+int computed_with_lambda = [] {
+ int *array = (int[]) { 1, 3, 5, 7 };
+ return array[0];
+}();
+// CHECK-LABEL: define internal i32 @{{.*}}clEv
+// CHECK: alloca [4 x i32]
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 0c2193fb07f2..c4962bc08ad6 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, 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" }
+ // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 1, i32 2), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 2, i32 2), 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, i32 0, i32 2) }
+ // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, inrange 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, i32 0, i32 2), i32 42 }
+ // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, inrange i32 0, i32 2), i32 42 }
TemplateClass<int> t;
}
diff --git a/test/CodeGenCXX/constructor-destructor-return-this.cpp b/test/CodeGenCXX/constructor-destructor-return-this.cpp
index 9d47d1706bbe..164fda3c1c38 100644
--- a/test/CodeGenCXX/constructor-destructor-return-this.cpp
+++ b/test/CodeGenCXX/constructor-destructor-return-this.cpp
@@ -111,7 +111,7 @@ D::~D() { }
// CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this)
// CHECKMS-LABEL: define x86_thiscallcc %class.D* @"\01??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived)
-// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D*)
+// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D* %this)
class E {
public:
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index c78534a218de..fe15ccf8fef5 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, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+ // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+ // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+ // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
// CHECK-NEXT: ret void
B::B(int x) : A(x + 5) {}
}
@@ -207,20 +207,17 @@ namespace PR10720 {
// CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_
// CHECK-PR10720-NOT: ret
- // CHECK-PR10720: load
- // CHECK-PR10720: icmp ult
- // CHECK-PR10720-NEXT: br i1
// CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_
- // CHECK-PR10720-NEXT: br label
+ // CHECK-PR10720: icmp eq
+ // CHECK-PR10720-NEXT: br i1
// CHECK-PR10720: ret void
// CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_
// CHECK-PR10720-NOT: ret
// CHECK-PR10720: load
- // CHECK-PR10720: icmp ult
- // CHECK-PR10720-NEXT: br i1
// CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_
- // CHECK-PR10720-NEXT: br label
+ // CHECK-PR10720: icmp eq
+ // CHECK-PR10720-NEXT: br i1
// CHECK-PR10720: ret void
pair2(pair2&&) = default;
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
index c263b7ebf952..26b6b4851f5a 100644
--- a/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -74,3 +74,23 @@ namespace PR12139 {
return a.value;
}
}
+
+namespace ElidableCallIsNotCopyCtor {
+ struct A { A(const A&); };
+ struct B : A {
+ B(B&);
+ B(A);
+ B(int);
+ };
+ void f() {
+ // Here, we construct via B(int) then B(A). The B(A) construction is
+ // elidable, but we don't have an AST representation for the case where we
+ // must elide not only a constructor call but also some argument
+ // conversions, so we don't elide it.
+ // CHECK-LABEL: define void @_ZN25ElidableCallIsNotCopyCtor1fEv(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1Ei(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1AC1ERKS0_(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1ENS_1AE(
+ B b = 0;
+ }
+}
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 9790ca882c6b..9d7e18e80f67 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, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
index 4928c61488e9..5a2cc1440f74 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, i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN12rdar138169401AE, i32 0, inrange 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/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp
index 018e958aab53..6826ee5796ca 100644
--- a/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
-// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns > %t
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes > %t
// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
@@ -8,7 +8,7 @@
// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t %s
-// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck --check-prefix=COFF %s
+// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck --check-prefix=COFF %s
namespace test1 {
// Test that we produce the apropriate comdats when creating aliases to
@@ -172,7 +172,7 @@ void zed() {
}
}
-// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
+// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant { [4 x i8*] } {{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
// r194296 replaced C::~C with B::~B without emitting the later.
class A {
diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp
index 6a3a394e047a..fbff07802676 100644
--- a/test/CodeGenCXX/cxx11-exception-spec.cpp
+++ b/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -121,7 +121,7 @@ void j() {
}
// CHECK: attributes [[NONE]] = { {{.*}} }
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
// CHECK: attributes [[NUW2]] = { nounwind{{.*}} }
diff --git a/test/CodeGenCXX/cxx11-noreturn.cpp b/test/CodeGenCXX/cxx11-noreturn.cpp
index b876bb9661ba..58a5a377133a 100644
--- a/test/CodeGenCXX/cxx11-noreturn.cpp
+++ b/test/CodeGenCXX/cxx11-noreturn.cpp
@@ -7,4 +7,4 @@ int g();
while (g()) {}
}
-// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} }
+// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} }
diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
index 50629b590562..6d0ae8a09e65 100644
--- a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
+++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
@@ -51,8 +51,8 @@ C n{};
// CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
// CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
-// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
// CHECK: load i8*, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
+// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
// CHECK: getelementptr inbounds i8, i8* %{{.*}}, {{.*}} %{{.*}}
// CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)
// CHECK: call i32 @_ZN1A1fEv({{.*}} @a)
diff --git a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
index 8c0b8c22096d..bc775568aaf1 100644
--- a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK
// expected-no-diagnostics
// The variable template specialization x<Foo> generated in each file
diff --git a/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
new file mode 100644
index 000000000000..437597d963b0
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
@@ -0,0 +1,206 @@
+// Check that delete exprs call aligned (de)allocation functions if
+// -faligned-allocation is passed in both C++11 and C++14.
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+
+// Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z.
+// RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
+// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
+
+// CHECK-UNALIGNED-NOT: _Znwm_St11align_val_t
+// CHECK-UNALIGNED-NOT: _Znam_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdlPv_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdaPv_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdlPvm_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdaPvm_St11align_val_t
+
+typedef decltype(sizeof(0)) size_t;
+namespace std { enum class align_val_t : size_t {}; }
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+// Global new and delete.
+// ======================
+struct OVERALIGNED A { A(); int n[128]; };
+
+// CHECK-LABEL: define {{.*}} @_Z2a0v()
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32)
+// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+void *a0() { return new A; }
+
+// CHECK-LABEL: define {{.*}} @_Z2a1l(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-NOT: store
+// CHECK: invoke void @_ZN1AC1Ev(
+// CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+void *a1(long n) { return new A[n]; }
+
+// CHECK-LABEL: define {{.*}} @_Z2a2P1A(
+// CHECK: call void @_ZdlPvmSt11align_val_t(i8* %{{.*}}, i64 512, i64 32) #9
+void a2(A *p) { delete p; }
+
+// CHECK-LABEL: define {{.*}} @_Z2a3P1A(
+// CHECK: call void @_ZdaPvSt11align_val_t(i8* %{{.*}}, i64 32) #9
+void a3(A *p) { delete[] p; }
+
+
+// Class-specific usual new and delete.
+// ====================================
+struct OVERALIGNED B {
+ B();
+ // These are just a distraction. We should ignore them.
+ void *operator new(size_t);
+ void operator delete(void*, size_t);
+ void operator delete[](void*, size_t);
+
+ void *operator new(size_t, std::align_val_t);
+ void operator delete(void*, std::align_val_t);
+ void operator delete[](void*, std::align_val_t);
+
+ int n[128];
+};
+
+// CHECK-LABEL: define {{.*}} @_Z2b0v()
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 32)
+// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+void *b0() { return new B; }
+
+// CHECK-LABEL: define {{.*}} @_Z2b1l(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-NOT: store
+// CHECK: invoke void @_ZN1BC1Ev(
+// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+void *b1(long n) { return new B[n]; }
+
+// CHECK-LABEL: define {{.*}} @_Z2b2P1B(
+// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %{{.*}}, i64 32)
+void b2(B *p) { delete p; }
+
+// CHECK-LABEL: define {{.*}} @_Z2b3P1B(
+// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %{{.*}}, i64 32)
+void b3(B *p) { delete[] p; }
+
+struct OVERALIGNED C {
+ C();
+ void *operator new[](size_t, std::align_val_t);
+ void operator delete[](void*, size_t, std::align_val_t);
+
+ // It doesn't matter that we have an unaligned operator delete[] that doesn't
+ // want the size. What matters is that the aligned one does.
+ void operator delete[](void*);
+};
+
+// This one has an array cookie.
+// CHECK-LABEL: define {{.*}} @_Z2b4l(
+// CHECK: call {{.*}} @llvm.umul.with.overflow{{.*}}i64 32
+// CHECK: call {{.*}} @llvm.uadd.with.overflow{{.*}}i64 32
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1CnaEmSt11align_val_t(i64 %{{.*}}, i64 32)
+// CHECK: store
+// CHECK: call void @_ZN1CC1Ev(
+//
+// Note, we're still calling a placement allocation function, and there is no
+// matching placement operator delete. =(
+// FIXME: This seems broken.
+// CHECK-NOT: call void @_ZN1CdaEPvmSt11align_val_t(
+#ifndef UNALIGNED
+void *b4(long n) { return new C[n]; }
+#endif
+
+// CHECK-LABEL: define {{.*}} @_Z2b5P1C(
+// CHECK: mul i64{{.*}} 32
+// CHECK: add i64{{.*}} 32
+// CHECK: call void @_ZN1CdaEPvmSt11align_val_t(
+void b5(C *p) { delete[] p; }
+
+
+// Global placement new.
+// =====================
+
+struct Q { int n; } q;
+void *operator new(size_t, Q);
+void *operator new(size_t, std::align_val_t, Q);
+void operator delete(void*, Q);
+void operator delete(void*, std::align_val_t, Q);
+
+// CHECK-LABEL: define {{.*}} @_Z2c0v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t1Q(i64 512, i64 32, i32 %
+// CHECK: call void @_ZdlPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
+void *c0() { return new (q) A; }
+
+
+// Class-specific placement new.
+// =============================
+
+struct OVERALIGNED D {
+ D();
+ void *operator new(size_t, Q);
+ void *operator new(size_t, std::align_val_t, Q);
+ void operator delete(void*, Q);
+ void operator delete(void*, std::align_val_t, Q);
+};
+
+// CHECK-LABEL: define {{.*}} @_Z2d0v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1DnwEmSt11align_val_t1Q(i64 32, i64 32, i32 %
+// CHECK: call void @_ZN1DdlEPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
+void *d0() { return new (q) D; }
+
+
+// Calling aligned new with placement syntax.
+// ==========================================
+
+#ifndef UNALIGNED
+// CHECK-LABEL: define {{.*}} @_Z2e0v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 5)
+// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 5)
+void *e0() { return new (std::align_val_t(5)) A; }
+
+// CHECK-LABEL: define {{.*}} @_Z2e1v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 5)
+// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 5)
+void *e1() { return new (std::align_val_t(5)) B; }
+#endif
+
+// Variadic placement/non-placement allocation functions.
+// ======================================================
+
+struct OVERALIGNED F {
+ F();
+ void *operator new(size_t, ...);
+ void operator delete(void*, ...);
+ int n[128];
+};
+
+// CHECK-LABEL: define {{.*}} @_Z2f0v(
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32)
+// Non-placement allocation function, uses normal deallocation lookup which
+// cares about whether a parameter has type std::align_val_t.
+// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]])
+void *f0() { return new F; }
+
+// CHECK-LABEL: define {{.*}} @_Z2f1v(
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32, i32 %
+// Placement allocation function, uses placement deallocation matching, which
+// passes same arguments and therefore includes alignment.
+// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]], i64 32, i32 %
+void *f1() { return new (q) F; }
+
+struct OVERALIGNED G {
+ G();
+ void *operator new(size_t, std::align_val_t, ...);
+ void operator delete(void*, std::align_val_t, ...);
+ int n[128];
+};
+#ifndef UNALIGNED
+// CHECK-LABEL: define {{.*}} @_Z2g0v
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32)
+// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32)
+void *g0() { return new G; }
+
+// CHECK-LABEL: define {{.*}} @_Z2g1v
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32, i32 %
+// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32, i32 %
+void *g1() { return new (q) G; }
+#endif
diff --git a/test/CodeGenCXX/cxx1z-constexpr-if.cpp b/test/CodeGenCXX/cxx1z-constexpr-if.cpp
index 80a397f51e9a..14695363b331 100644
--- a/test/CodeGenCXX/cxx1z-constexpr-if.cpp
+++ b/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -2,7 +2,15 @@
void should_be_used_1();
void should_be_used_2();
+void should_be_used_3();
void should_not_be_used();
+
+struct A {
+ constexpr explicit operator bool() const {
+ return true;
+ }
+};
+
void f() {
if constexpr (false)
should_not_be_used();
@@ -15,7 +23,12 @@ void f() {
goto foo;
foo: should_not_be_used();
}
+ if constexpr (A())
+ should_be_used_3();
+ else
+ should_not_be_used();
}
// CHECK: should_be_used_1
// CHECK: should_be_used_2
+// CHECK: should_be_used_3
diff --git a/test/CodeGenCXX/cxx1z-copy-omission.cpp b/test/CodeGenCXX/cxx1z-copy-omission.cpp
new file mode 100644
index 000000000000..234e4b12589c
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-copy-omission.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s
+
+struct A {
+ A(int);
+ A(A&&);
+ A(const A&);
+ ~A();
+
+ int arr[10];
+};
+
+A f();
+void h();
+
+// CHECK-LABEL: define {{.*}} @_Z1gv(
+void g() {
+ // CHECK: %[[A:.*]] = alloca
+ // CHECK-NOT: alloca
+ // CHECK-NOT: call
+ // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])
+ A a = A( A{ f() } );
+ // CHECK-NOT: call
+
+ // CHECK: call void @_Z1hv(
+ h();
+ // CHECK-NOT: call
+
+ // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
+ // CHECK-NOT: call
+ // CHECK-LABEL: }
+}
+
+void f(A);
+
+// CHECK-LABEL: define {{.*}} @_Z1hv(
+void h() {
+ // CHECK: %[[A:.*]] = alloca
+ // CHECK-NOT: alloca
+ // CHECK-NOT: call
+
+ // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])
+ // CHECK-NOT: call
+ // CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]])
+ f(f());
+ // CHECK-NOT: call
+ // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
+
+ // CHECK: call void @_Z1hv(
+ h();
+
+ // CHECK-NOT: call
+ // CHECK-LABEL: }
+}
+
+// We still pass classes with trivial copy/move constructors and destructors in
+// registers, even if the copy is formally omitted.
+struct B {
+ B(int);
+ int n;
+};
+
+B fB();
+void fB(B);
+
+// CHECK-LABEL: define {{.*}} @_Z1iv(
+void i() {
+ // CHECK: %[[B:.*]] = alloca
+ // CHECK-NOT: alloca
+ // CHECK-NOT: call
+
+ // CHECK: %[[B_N:.*]] = call i32 @_Z2fBv()
+ // CHECK-NOT: call
+ // CHECK: store i32 %[[B_N]],
+ // CHECK-NOT: call
+ // CHECK: %[[B_N:.*]] = load i32
+ // CHECK-NOT: call
+ // CHECK: call void @_Z2fB1B(i32 %[[B_N]])
+ fB(fB());
+
+ // CHECK-LABEL: }
+}
diff --git a/test/CodeGenCXX/cxx1z-decomposition.cpp b/test/CodeGenCXX/cxx1z-decomposition.cpp
new file mode 100644
index 000000000000..b9212006053b
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-decomposition.cpp
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ template<typename> struct tuple_size;
+ template<size_t, typename> struct tuple_element;
+}
+
+struct Y { int n; };
+struct X { X(); X(Y); X(const X&); ~X(); };
+
+struct A { int a : 13; bool b; };
+
+struct B {};
+template<> struct std::tuple_size<B> { enum { value = 2 }; };
+template<> struct std::tuple_element<0,B> { using type = X; };
+template<> struct std::tuple_element<1,B> { using type = const int&; };
+template<int N> auto get(B) {
+ if constexpr (N == 0)
+ return Y();
+ else
+ return 0.0;
+}
+
+using C = int[2];
+
+typedef int D __attribute__((ext_vector_type(2)));
+
+using E = _Complex int;
+
+template<typename T> T &make();
+
+// CHECK: @_ZDC2a12a2E = global {{.*}} zeroinitializer, align 4
+auto [a1, a2] = make<A>();
+// CHECK: @_ZDC2b12b2E = global {{.*}} zeroinitializer, align 1
+// CHECK: @b1 = global {{.*}}* null, align 8
+// CHECK: @_ZGR2b1_ = internal global {{.*}} zeroinitializer, align 1
+// CHECK: @b2 = global i32* null, align 8
+// CHECK: @_ZGR2b2_ = internal global i32 0, align 4
+auto [b1, b2] = make<B>();
+// CHECK: @_ZDC2c12c2E = global [2 x i32]* null, align 8
+auto &[c1, c2] = make<C>();
+// CHECK: @_ZDC2d12d2E = global <2 x i32> zeroinitializer, align 8
+auto [d1, d2] = make<D>();
+// CHECK: @_ZDC2e12e2E = global { i32, i32 } zeroinitializer, align 4
+auto [e1, e2] = make<E>();
+
+// CHECK: call {{.*}}* @_Z4makeI1AERT_v()
+// CHECK: call {{.*}}memcpy{{.*}}@_ZDC2a12a2E
+
+// CHECK: @_Z4makeI1BERT_v()
+// CHECK: call i32 @_Z3getILi0EEDa1B()
+// CHECK: call void @_ZN1XC1E1Y({{.*}}* @_ZGR2b1_, i32
+// CHECK: call i32 @__cxa_atexit({{.*}}@_ZN1XD1Ev{{.*}}@_ZGR2b1_
+// CHECK: store {{.*}}* @_ZGR2b1_,
+//
+// CHECK: call double @_Z3getILi1EEDa1B()
+// CHECK: fptosi double %{{.*}} to i32
+// CHECK: store i32 %{{.*}}, i32* @_ZGR2b2_
+// CHECK: store i32* @_ZGR2b2_, i32** @b2
+
+// CHECK: call {{.*}}* @_Z4makeIA2_iERT_v()
+// CHECK: store {{.*}}, [2 x i32]** @_ZDC2c12c2E
+
+// CHECK: call {{.*}}* @_Z4makeIDv2_iERT_v()
+// CHECK: store {{.*}}, <2 x i32>* @_ZDC2d12d2E, align 8
+
+// CHECK: call {{.*}}* @_Z4makeICiERT_v()
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 0)
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 1)
+
+// CHECK: define i32 @_Z12test_globalsv()
+int test_globals() {
+ return a2 + b2 + c2 + d2 + e2;
+ // CHECK: load i8, i8* getelementptr inbounds (%struct.A, %struct.A* @_ZDC2a12a2E, i32 0, i32 1)
+ //
+ // CHECK: %[[b2:.*]] = load i32*, i32** @b2
+ // CHECK: load i32, i32* %[[b2]]
+ //
+ // CHECK: %[[c1c2:.*]] = load [2 x i32]*, [2 x i32]** @_ZDC2c12c2E
+ // CHECK: %[[c2:.*]] = getelementptr inbounds [2 x i32], [2 x i32]* %[[c1c2]], i64 0, i64 1
+ // CHECK: load i32, i32* %[[c2]]
+ //
+ // CHECK: %[[d1d2:.*]] = load <2 x i32>, <2 x i32>* @_ZDC2d12d2E
+ // CHECK: extractelement <2 x i32> %[[d1d2]], i32 1
+ //
+ // CHECK: load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 1)
+}
+
+// CHECK: define i32 @_Z11test_localsv()
+int test_locals() {
+ auto [b1, b2] = make<B>();
+
+ // CHECK: @_Z4makeI1BERT_v()
+ // CHECK: call i32 @_Z3getILi0EEDa1B()
+ // CHECK: call void @_ZN1XC1E1Y({{.*}}* %[[b1:.*]], i32
+ //
+ // CHECK: call double @_Z3getILi1EEDa1B()
+ // CHECK: %[[cvt:.*]] = fptosi double %{{.*}} to i32
+ // CHECK: store i32 %[[cvt]], i32* %[[b2:.*]],
+ // CHECK: store i32* %[[b2]], i32** %[[b2ref:.*]],
+
+ return b2;
+ // CHECK: %[[b2:.*]] = load i32*, i32** %[[b2ref]]
+ // CHECK: load i32, i32* %[[b2]]
+
+ // CHECK: call {{.*}}@_ZN1XD1Ev({{.*}}%[[b1]])
+}
+
+// CHECK: define void @_Z13test_bitfieldR1A(
+void test_bitfield(A &a) {
+ auto &[a1, a2] = a;
+ a1 = 5;
+ // CHECK: load i16, i16* %[[BITFIELD:.*]],
+ // CHECK: and i16 %{{.*}}, -8192
+ // CHECK: or i16 %{{.*}}, 5
+ // CHECK: store i16 %{{.*}}, i16* %[[BITFIELD]],
+}
diff --git a/test/CodeGenCXX/cxx1z-eval-order.cpp b/test/CodeGenCXX/cxx1z-eval-order.cpp
new file mode 100644
index 000000000000..1106719a4748
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-eval-order.cpp
@@ -0,0 +1,271 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
+
+struct B;
+struct A {
+ A();
+ A(const A&);
+
+ void operator[](B b);
+
+ int a_member_f(B);
+};
+struct B {
+ B();
+ ~B();
+};
+
+struct C {
+ operator int *();
+ A *operator->();
+ void operator->*(A);
+ friend void operator->*(C, B);
+
+ friend void operator<<(C, B);
+ friend void operator>>(C, B);
+ void operator<<(A);
+ void operator>>(A);
+
+ void operator=(A);
+ void operator+=(A);
+ friend void operator+=(C, B);
+
+ void operator,(A);
+ friend void operator,(C, B);
+
+ void operator&&(A);
+ void operator||(A);
+ friend void operator&&(C, B);
+ friend void operator||(C, B);
+};
+
+A make_a();
+A *make_a_ptr();
+int A::*make_mem_ptr_a();
+void (A::*make_mem_fn_ptr_a())();
+B make_b();
+C make_c();
+void side_effect();
+
+void callee(A);
+void (*get_f())(A);
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}(
+void postfix_before_args() {
+ // CHECK: call {{.*}}@{{.*}}get_f{{.*}}(
+ // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
+ // CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"(
+ // CHECK: call {{.*}}%{{.*}}(
+ get_f()(A{});
+
+ // CHECK: call {{.*}}@{{.*}}side_effect{{.*}}(
+ // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
+ // CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"(
+ // CHECK: call {{.*}}@{{.*}}callee{{.*}}(
+ (side_effect(), callee)(A{});
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}dot_lhs_before_rhs{{.*}}(
+void dot_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+ make_a().a_member_f(make_b());
+
+ // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+ make_a_ptr()->a_member_f(make_b());
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+ make_c()->a_member_f(make_b());
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}array_lhs_before_rhs{{.*}}(
+void array_lhs_before_rhs() {
+ int (&get_arr())[10];
+ extern int get_index();
+
+ // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ get_arr()[get_index()] = 0;
+
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
+ get_index()[get_arr()] = 0;
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call
+ make_a()[make_b()];
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ // CHECK: call
+ make_c()[get_index()] = 0;
+
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call
+ get_index()[make_c()] = 0;
+// CHECK: }
+}
+
+
+void *operator new(decltype(sizeof(0)), C);
+
+// CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}(
+void alloc_before_init() {
+ struct Q { Q(A) {} };
+ // CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}(
+ // CHECK-WINDOWS: call {{.*}}@"\01??2@YAP{{EAX_K|AXI}}@Z"(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ delete new Q(make_a());
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ new (make_c()) Q(make_a());
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}(
+int dotstar_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
+ int a = make_a().*make_mem_ptr_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
+ int b = make_a_ptr()->*make_mem_ptr_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c()->*make_a();
+
+ // FIXME: For MS ABI, the order of destruction of parameters here will not be
+ // reverse construction order (parameters are destroyed left-to-right in the
+ // callee). That sadly seems unavoidable; the rules are not implementable as
+ // specified. If we changed parameter destruction order for these functions
+ // to right-to-left, we could make the destruction order match for all cases
+ // other than indirect calls, but we can't completely avoid the problem.
+ //
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c()->*make_b();
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
+ // CHECK: call
+ (make_a().*make_mem_fn_ptr_a())();
+
+ // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
+ // CHECK: call
+ (make_a_ptr()->*make_mem_fn_ptr_a())();
+
+ return a + b;
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}(
+void assign_rhs_before_lhs() {
+ extern int &lhs_ref(), rhs();
+
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+ lhs_ref() = rhs();
+
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+ lhs_ref() += rhs();
+
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+ lhs_ref() %= rhs();
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ make_c() = make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ make_c() += make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ make_c() += make_b();
+// CHECK: }
+}
+
+// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}(
+void shift_lhs_before_rhs() {
+ extern int lhs(), rhs();
+
+ // CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ (void)(lhs() << rhs());
+
+ // CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ (void)(lhs() >> rhs());
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() << make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() >> make_a();
+
+ // FIXME: This is not correct for Windows ABIs, see above.
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() << make_b();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() >> make_b();
+// CHECK: }
+}
+
+// CHECK-LABEL: define {{.*}}@{{.*}}comma_lhs_before_rhs{{.*}}(
+void comma_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() , make_a();
+
+ // FIXME: This is not correct for Windows ABIs, see above.
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() , make_b();
+}
+
+// CHECK-LABEL: define {{.*}}@{{.*}}andor_lhs_before_rhs{{.*}}(
+void andor_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() && make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() || make_a();
+
+ // FIXME: This is not correct for Windows ABIs, see above.
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() && make_b();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() || make_b();
+}
diff --git a/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp b/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp
new file mode 100644
index 000000000000..d2d06fbd2654
--- /dev/null
+++ b/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++1z -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+// CHECK-LABEL: define {{.*}} @_Z11builtin_newm(
+// CHECK: call {{.*}} @_Znwm(
+void *builtin_new(unsigned long n) { return __builtin_operator_new(n); }
+
+// CHECK-LABEL: define {{.*}} @_Z14builtin_deletePv(
+// CHECK: call {{.*}} @_ZdlPv(
+void builtin_delete(void *p) { return __builtin_operator_delete(p); }
diff --git a/test/CodeGenCXX/debug-info-access.cpp b/test/CodeGenCXX/debug-info-access.cpp
index 41b7f71fcecb..82f29ea4d38a 100644
--- a/test/CodeGenCXX/debug-info-access.cpp
+++ b/test/CodeGenCXX/debug-info-access.cpp
@@ -39,6 +39,6 @@ private:
// CHECK-SAME: flags: DIFlagPrototyped,
void free() {}
+U u;
A a;
B b;
-U u;
diff --git a/test/CodeGenCXX/debug-info-alias.cpp b/test/CodeGenCXX/debug-info-alias.cpp
index 90476439e782..8c3f8447de69 100644
--- a/test/CodeGenCXX/debug-info-alias.cpp
+++ b/test/CodeGenCXX/debug-info-alias.cpp
@@ -14,8 +14,6 @@ bar
}
// CHECK: !DIGlobalVariable(name: "bi",{{.*}} type: [[BINT:![0-9]+]]
-// CHECK: [[BINT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<int>"
-// CHECK-SAME: line: 42,
x::bar<int> bi;
// CHECK: !DIGlobalVariable(name: "bf",{{.*}} type: [[BFLOAT:![0-9]+]]
// CHECK: [[BFLOAT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<float>"
@@ -37,3 +35,6 @@ tv<int> *tvp;
using v = void;
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "v"
v *vp;
+
+// CHECK: [[BINT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<int>"
+// CHECK-SAME: line: 42,
diff --git a/test/CodeGenCXX/debug-info-anon-namespace.cpp b/test/CodeGenCXX/debug-info-anon-namespace.cpp
index 4e3e08af2b74..79298deaf8b1 100644
--- a/test/CodeGenCXX/debug-info-anon-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-anon-namespace.cpp
@@ -19,8 +19,9 @@ int *b2 = &a2;
// PS4: [[NS:![0-9]+]] = !DINamespace
+// PS4: [[CU:![0-9]+]] = distinct !DICompileUnit
// PS4: [[NS2:![0-9]+]] = !DINamespace
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: [[NS]])
+// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]])
// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], line: {{[0-9]+}})
// NON-PS4-NOT: !DIImportedEntity
diff --git a/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/test/CodeGenCXX/debug-info-anon-union-vars.cpp
index b844d429447b..61b3c7c0526c 100644
--- a/test/CodeGenCXX/debug-info-anon-union-vars.cpp
+++ b/test/CodeGenCXX/debug-info-anon-union-vars.cpp
@@ -45,8 +45,8 @@ void instantiate(int x) {
}
// 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: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp",
// CHECK: !DIGlobalVariable(name: "a",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
// CHECK: !DIGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
// CHECK: !DIGlobalVariable(name: "result", {{.*}} isLocal: false, isDefinition: true
diff --git a/test/CodeGenCXX/debug-info-calling-conventions.cpp b/test/CodeGenCXX/debug-info-calling-conventions.cpp
index 51d801e35ef6..db7fbd23405d 100644
--- a/test/CodeGenCXX/debug-info-calling-conventions.cpp
+++ b/test/CodeGenCXX/debug-info-calling-conventions.cpp
@@ -8,7 +8,7 @@ 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)
+// CHECK: ![[thisptrty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{.*}}, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
void cdeclcc() {}
void __fastcall fastcallcc() {}
diff --git a/test/CodeGenCXX/debug-info-class-nolimit.cpp b/test/CodeGenCXX/debug-info-class-nolimit.cpp
index ce47f9fa495a..0b3b38dd17b1 100644
--- a/test/CodeGenCXX/debug-info-class-nolimit.cpp
+++ b/test/CodeGenCXX/debug-info-class-nolimit.cpp
@@ -1,8 +1,26 @@
-// RUN: %clang_cc1 -triple x86_64-unk-unk -debug-info-kind=standalone -o - -emit-llvm %s | FileCheck %s
-// On Darwin, "full" debug info is the default, so really these tests are
-// identical, as cc1 no longer chooses the effective value of DebugInfoKind.
// RUN: %clang_cc1 -triple x86_64-apple-darwin -debug-info-kind=standalone -o - -emit-llvm %s | FileCheck %s
+// We had a bug in -fstandalone-debug where UnicodeString would not be completed
+// when it was required to be complete. This orginally manifested as an
+// assertion in CodeView emission on Windows with some dllexport stuff, but it's
+// more general than that.
+
+struct UnicodeString;
+UnicodeString *force_fwd_decl;
+struct UnicodeString {
+private:
+ virtual ~UnicodeString();
+};
+struct UseCompleteType {
+ UseCompleteType();
+ ~UseCompleteType();
+ UnicodeString currencySpcAfterSym[1];
+};
+UseCompleteType require_complete;
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "UnicodeString"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
namespace rdar14101097_1 { // see also PR16214
// Check that we emit debug info for the definition of a struct if the
// definition is available, even if it's used via a pointer wrapped in a
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
index d03c0845dd6b..d572eef68abf 100644
--- a/test/CodeGenCXX/debug-info-class.cpp
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -122,6 +122,7 @@ int main(int argc, char **argv) {
// CHECK: [[C_DTOR]] = !DISubprogram(name: "~C"
// CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D"
+// CHECK-NOT: size:
// CHECK-SAME: DIFlagFwdDecl
// CHECK-SAME: identifier: "_ZTS1D"
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E"
diff --git a/test/CodeGenCXX/debug-info-codeview-injected-class.cpp b/test/CodeGenCXX/debug-info-codeview-injected-class.cpp
new file mode 100644
index 000000000000..b421b2bf8bd9
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-codeview-injected-class.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+// The injected class names in this test were accidentally making it into our
+// nested class record debug info. Make sure they don't appear there.
+
+// PR28790
+
+struct A {
+ const char *m_fn1();
+ template <typename> class B;
+ template <typename> class C;
+ template <typename FunctionIdT> class C<B<FunctionIdT>>;
+};
+const char *A::m_fn1() { return nullptr; }
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[m_fn1:[0-9]+]]}
+
+// CHECK: ![[m_fn1]] = !DISubprogram(name: "m_fn1",
diff --git a/test/CodeGenCXX/debug-info-cxx1y.cpp b/test/CodeGenCXX/debug-info-cxx1y.cpp
index 36b3e09180c6..403424e2d6a8 100644
--- a/test/CodeGenCXX/debug-info-cxx1y.cpp
+++ b/test/CodeGenCXX/debug-info-cxx1y.cpp
@@ -3,9 +3,6 @@
// CHECK: imports: [[IMPS:![0-9]*]]
// CHECK: [[EMPTY:![0-9]*]] = !{}
-// CHECK: [[FOO:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
-// CHECK-SAME: elements: [[EMPTY]]
-
// CHECK: [[IMPS]] = !{[[IMP:![0-9]*]]}
// CHECK: [[IMP]] = !DIImportedEntity(
// CHECK-SAME: entity: [[F3:![0-9]*]]
@@ -15,6 +12,9 @@
// CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]}
// CHECK: [[INT]] = !DIBasicType(name: "int"
+// 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: [[FOO]]
// CHECK-SAME: type: [[SUBROUTINE_TYPE]]
diff --git a/test/CodeGenCXX/debug-info-dllimport-base-class.cpp b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
new file mode 100644
index 000000000000..855ecaaa4c90
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple i386-pc-windows -emit-llvm -gcodeview -debug-info-kind=limited -fms-compatibility %s -x c++ -o - | FileCheck %s
+
+// Ensure we emit debug info for the full definition of base classes that will
+// be imported from a DLL. Otherwise, the debugger wouldn't be able to show the
+// members.
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedAfterCompletion",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OutOfLineCtor",
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedBase",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedMethod",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+
+struct ImportedAfterCompletion;
+ImportedAfterCompletion *force_fwd_decl;
+struct __declspec(dllimport) ImportedAfterCompletion {
+ virtual ~ImportedAfterCompletion();
+};
+
+struct OutOfLineCtor {
+ OutOfLineCtor();
+ virtual void Foo();
+};
+
+struct __declspec(dllimport) ImportedBase {
+ ImportedBase();
+ virtual void Foo();
+};
+
+struct DerivedFromImported : public ImportedBase {};
+
+struct ImportedMethod {
+ ImportedMethod();
+ virtual void Foo();
+ static void __declspec(dllimport) create();
+};
+
+int main() {
+ ImportedAfterCompletion c;
+ OutOfLineCtor o;
+ DerivedFromImported d;
+ ImportedMethod m;
+}
diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
index f7a2cfe7bae6..3b23ebf7dedc 100644
--- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
+++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
@@ -19,6 +19,6 @@ protected:
Test t;
-// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "data"
+// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "data"
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index 44daf412d3ac..b615d5b09626 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -13,7 +13,7 @@ D d;
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "A"
// CHECK-SAME: line: 3
// CHECK-SAME: baseType: ![[INT:[0-9]+]]
-// CHECK-SAME: size: 32, align: 32
+// CHECK-SAME: size: 32
// CHECK-NOT: offset:
// CHECK-NOT: flags:
// CHECK-SAME: ){{$}}
@@ -21,7 +21,7 @@ D d;
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "B"
// CHECK-SAME: line: 4
// CHECK-SAME: baseType: ![[ULONG:[0-9]+]]
-// CHECK-SAME: size: 64, align: 64
+// CHECK-SAME: size: 64
// CHECK-NOT: offset:
// CHECK-NOT: flags:
// CHECK-SAME: ){{$}}
@@ -29,7 +29,7 @@ D d;
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "C"
// CHECK-SAME: line: 5
// CHECK-NOT: baseType:
-// CHECK-SAME: size: 32, align: 32
+// CHECK-SAME: size: 32
// CHECK-NOT: offset:
// CHECK-NOT: flags:
// CHECK-SAME: ){{$}}
@@ -91,7 +91,7 @@ void f2(E) {
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "D"
// CHECK-SAME: line: 6
-// CHECK-SAME: size: 16, align: 16
+// CHECK-SAME: size: 16
// CHECK-NOT: offset:
// CHECK-SAME: flags: DIFlagFwdDecl
diff --git a/test/CodeGenCXX/debug-info-flex-member.cpp b/test/CodeGenCXX/debug-info-flex-member.cpp
deleted file mode 100644
index 8dcdaeb935d0..000000000000
--- a/test/CodeGenCXX/debug-info-flex-member.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
-
-// CHECK: !DISubrange(count: -1)
-
-struct StructName {
- int member[];
-};
-
-struct StructName SN;
diff --git a/test/CodeGenCXX/debug-info-global.cpp b/test/CodeGenCXX/debug-info-global.cpp
index 795602380d20..5abc050431d1 100644
--- a/test/CodeGenCXX/debug-info-global.cpp
+++ b/test/CodeGenCXX/debug-info-global.cpp
@@ -15,7 +15,8 @@ int f1() {
// CHECK: [[GLOBALS]] = !{[[CNST:![0-9]*]]}
-// CHECK: [[CNST]] = distinct !DIGlobalVariable(name: "cnst",
-// CHECK-SAME: scope: [[NS:![0-9]*]]
+// CHECK: [[CNST]] = !DIGlobalVariableExpression(var: [[CNSTV:.*]], expr:
+// CHECK: [[CNSTV]] = 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 70b233cac4dc..126e1f6bd1b8 100644
--- a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
+++ b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
@@ -11,13 +11,13 @@ struct Bar {
// CHECK: !DIDerivedType(tag: DW_TAG_member, scope:
// CHECK-SAME: line: [[@LINE+4]]
// CHECK-SAME: baseType: ![[UNION:[0-9]+]]
- // CHECK-SAME: size: 32, align: 32, offset: 32
+ // CHECK-SAME: size: 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]]
// CHECK-SAME: baseType: ![[INT]]
- // CHECK-SAME: size: 32, align: 32
+ // CHECK-SAME: size: 32
// CHECK-NOT: offset:
// CHECK-SAME: ){{$}}
int i2;
diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp
index b3f9c32e0911..41770b135619 100644
--- a/test/CodeGenCXX/debug-info-line-if.cpp
+++ b/test/CodeGenCXX/debug-info-line-if.cpp
@@ -53,15 +53,19 @@ int main() {
// 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: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}})
- // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]}
- // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}})
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}})
- // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]}
- // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}})
+ // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}})
- // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]}
- // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}})
+ // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 401, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 405, scope: !{{.*}})
}
diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp
index 11653040109c..a1c4ef9eea25 100644
--- a/test/CodeGenCXX/debug-info-line.cpp
+++ b/test/CodeGenCXX/debug-info-line.cpp
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -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 -mllvm -no-discriminators -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s
int &src();
int *sink();
diff --git a/test/CodeGenCXX/debug-info-loops.cpp b/test/CodeGenCXX/debug-info-loops.cpp
new file mode 100644
index 000000000000..69948ea0f880
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-loops.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang -g -gcolumn-info -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+extern int v[2];
+int a = 0, b = 0;
+int main() {
+#line 100
+ for (int x : v) {
+ if (x)
+ ++b;
+ else
+ ++a;
+ }
+
+ // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]]
+
+#line 200
+ while (a)
+ if (b)
+ ++b;
+ else
+ ++a;
+ // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]]
+
+#line 300
+ for (unsigned i = 0; i < 100; i++) {
+ a++;
+ for (int y : v)
+ ++b;
+ }
+
+ // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]]
+ // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L4:![0-9]*]]
+
+
+ // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}})
+
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}})
+
+ // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}})
+ //
+ // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}})
+}
diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp
index 73d8b928269a..e0f9a284f2cf 100644
--- a/test/CodeGenCXX/debug-info-method.cpp
+++ b/test/CodeGenCXX/debug-info-method.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -debug-info-kind=limited %s -o - | FileCheck %s
+// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type
// 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: ![[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({{(cc: DW_CC_BORLAND_thiscall, )?}}types: ![[MEMFUNARGS:[0-9]+]])
// CHECK: ![[MEMFUNARGS]] = {{.*}}, ![[THISTYPE]],
diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp
index a146ce94176e..1bf8bab5f41c 100644
--- a/test/CodeGenCXX/debug-info-ms-abi.cpp
+++ b/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
// Tests that certain miscellaneous features work in the MS ABI.
@@ -11,20 +11,30 @@ struct Foo {
Foo f;
Foo::Nested n;
+// CHECK: ![[Nested:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
+// CHECK-SAME: identifier: ".?AUNested@Foo@@"
+
// CHECK: ![[Foo:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
// CHECK-SAME: identifier: ".?AUFoo@@"
-// CHECK: !DISubprogram(name: "f",
+// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]]}
+
+// CHECK: ![[vshape]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 96)
+
+// CHECK: ![[vptr]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Foo",
+// CHECK-SAME: baseType: ![[vptr_ty:[0-9]+]],
+
+// CHECK: ![[vptr_ty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[vshape]], size: 32
+
+// CHECK: ![[f]] = !DISubprogram(name: "f",
// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
-// CHECK: !DISubprogram(name: "g",
+// CHECK: ![[g]] = !DISubprogram(name: "g",
// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 1,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
-// CHECK: !DISubprogram(name: "h",
+// CHECK: ![[h]] = !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
index cef1eb8c5a09..5e2cb2190f0d 100644
--- a/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp
+++ b/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp
@@ -4,7 +4,6 @@ typedef struct {
} test1;
test1 gv1;
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "test1"
struct {
} test2;
@@ -18,3 +17,5 @@ test3 gv3;
void *use_test3 = &gv3;
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "<unnamed-type-test3>"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "test1"
diff --git a/test/CodeGenCXX/debug-info-ms-bitfields.cpp b/test/CodeGenCXX/debug-info-ms-bitfields.cpp
index 07d4c0c6c78a..e42330143bba 100644
--- a/test/CodeGenCXX/debug-info-ms-bitfields.cpp
+++ b/test/CodeGenCXX/debug-info-ms-bitfields.cpp
@@ -7,4 +7,4 @@ struct S {
short x : 8;
} s;
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, align: 16, offset: 16, flags: DIFlagBitField, extraData: i64 8)
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, 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
index 4b9f2a146896..1f4c90484b89 100644
--- a/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp
+++ b/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp
@@ -23,7 +23,6 @@ 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:[^, ]*]], {{.*}})
@@ -45,8 +44,10 @@ void (Incomplete::**ppmf)();
// CHECK-SAME: ){{$}}
// CHECK: distinct !DIGlobalVariable(name: "ppmd", {{.*}} type: ![[ppmd:[^, ]*]], {{.*}})
-// CHECK: ![[ppmd]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmd2:[^ ]*]], size: 64, align: 64)
+// CHECK: ![[ppmd]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmd2:[^ ]*]], size: 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: ![[ppmf]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmf2:[^ ]*]], size: 64)
// CHECK: ![[ppmf2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}}
+
+// CHECK: ![[pmd_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagSingleInheritance, {{.*}})
diff --git a/test/CodeGenCXX/debug-info-ms-vbase.cpp b/test/CodeGenCXX/debug-info-ms-vbase.cpp
new file mode 100644
index 000000000000..3de3a751cba1
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ms-vbase.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+// Tests virtual bases in the MS ABI.
+
+// CHECK: ![[NoPrimaryBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "NoPrimaryBase",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[NoPrimaryBase_base:[0-9]+]]}
+
+// CHECK: ![[NoPrimaryBase_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[NoPrimaryBase]],
+// CHECK-SAME: baseType: ![[HasVirtualMethod:[0-9]+]], offset: 4, flags: DIFlagVirtual)
+
+// CHECK: ![[HasVirtualMethod]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasVirtualMethod"
+
+// CHECK: ![[HasPrimaryBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasPrimaryBase",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[SecondaryVTable_base:[0-9]+]], ![[HasVirtualMethod_base:[0-9]+]], ![[vshape:[0-9]+]]}
+
+// CHECK: ![[SecondaryVTable_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]],
+// CHECK-SAME: baseType: ![[SecondaryVTable:[0-9]+]], offset: 4, flags: DIFlagVirtual)
+
+// CHECK: ![[SecondaryVTable]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SecondaryVTable"
+
+// CHECK: ![[HasVirtualMethod_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]], baseType: ![[HasVirtualMethod]])
+
+// CHECK: ![[HasIndirectVirtualBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasIndirectVirtualBase"
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasIndirectVirtualBase]], baseType: ![[HasPrimaryBase]]
+// CHECK-NOT: DIFlagIndirectVirtualBase
+// CHECK-SAME: )
+
+// CHECK: !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasIndirectVirtualBase]], baseType: ![[SecondaryVTable]]
+// CHECK-SAME: flags:
+// CHECK-SAME: DIFlagIndirectVirtualBase
+
+// CHECK: ![[DynamicNoVFPtr:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DynamicNoVFPtr",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[POD_base:[0-9]+]]}
+
+// CHECK: ![[POD_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[DynamicNoVFPtr]],
+// CHECK-SAME: baseType: ![[POD:[0-9]+]], offset: 4, flags: DIFlagVirtual)
+
+// CHECK: ![[POD]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "POD"
+
+struct POD { int pod; };
+
+struct DynamicNoVFPtr : virtual POD { };
+
+DynamicNoVFPtr dynamic_no_vfptr;
+
+struct HasVirtualMethod { virtual void f(); };
+
+struct NoPrimaryBase : virtual HasVirtualMethod { };
+
+NoPrimaryBase no_primary_base;
+
+struct SecondaryVTable { virtual void g(); };
+
+struct HasPrimaryBase : virtual SecondaryVTable, HasVirtualMethod { };
+
+HasPrimaryBase has_primary_base;
+
+struct HasIndirectVirtualBase : public HasPrimaryBase {};
+
+HasIndirectVirtualBase has_indirect_virtual_base;
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index 060a5cea636c..c75c40766a37 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -debug-info-kind=limited -S -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -debug-info-kind=line-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s
-// RUN: %clang_cc1 -debug-info-kind=standalone -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=limited -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=line-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s
namespace A {
#line 1 "foo.cpp"
@@ -49,14 +49,15 @@ using B::i;
namespace B {
int var_fwd = i;
}
+inline namespace I {
+int var_i;
+}
}
void B::func_fwd() {}
// This should work even if 'i' and 'func' were declarations & not definitions,
// but it doesn't yet.
-// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit(
-// CHECK-SAME: imports: [[MODULES:![0-9]*]]
// 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"
@@ -65,6 +66,10 @@ void B::func_fwd() {}
// CHECK: [[VAR_FWD:![0-9]+]] = distinct !DIGlobalVariable(name: "var_fwd",{{.*}} scope: [[NS]],
// CHECK-SAME: line: 44
// CHECK-SAME: isDefinition: true
+// CHECK: distinct !DIGlobalVariable(name: "var_i",{{.*}} scope: [[INLINE:![0-9]+]],
+// CHECK: [[INLINE]] = !DINamespace(name: "I", scope: [[CTXT]], file: [[FOOCPP]], line: 46, exportSymbols: true)
+// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit(
+// CHECK-SAME: imports: [[MODULES:![0-9]*]]
// 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)
@@ -101,7 +106,7 @@ void B::func_fwd() {}
// 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: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 50,{{.*}} isDefinition: true
// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
// CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit(
diff --git a/test/CodeGenCXX/debug-info-rvalue-ref.cpp b/test/CodeGenCXX/debug-info-rvalue-ref.cpp
index edb93ae46cda..de0f65ad9a02 100644
--- a/test/CodeGenCXX/debug-info-rvalue-ref.cpp
+++ b/test/CodeGenCXX/debug-info-rvalue-ref.cpp
@@ -8,5 +8,5 @@ void foo (int &&i)
printf("%d\n", i);
}
-// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[INT:[0-9]+]], size: 64, align: 64)
+// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[INT:[0-9]+]], size: 64)
// CHECK: ![[INT]] = !DIBasicType(name: "int"
diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp
index ed8ae015cfc3..c777ccb2aba2 100644
--- a/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/test/CodeGenCXX/debug-info-static-member.cpp
@@ -3,6 +3,10 @@
// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck %s
// PR14471
+// CHECK: @_ZN1C1aE = global i32 4, align 4, !dbg [[A:![0-9]+]]
+// CHECK: @_ZN1C1bE = global i32 2, align 4, !dbg [[B:![0-9]+]]
+// CHECK: @_ZN1C1cE = global i32 1, align 4, !dbg [[C:![0-9]+]]
+
enum X {
Y
};
@@ -28,6 +32,10 @@ public:
// why the definition of "a" comes before the declarations while
// "b" and "c" come after.
+// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]])
+// CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
+// CHECK-SAME: declaration: ![[DECL_A:[0-9]+]])
+//
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X")
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct"
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var"
@@ -36,16 +44,24 @@ public:
// 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: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]])
+// CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
+// CHECK-SAME: declaration: ![[DECL_B:[0-9]+]])
+// CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
// CHECK-NOT: size:
// CHECK-NOT: align:
// CHECK-NOT: offset:
-// CHECK-SAME: flags: DIFlagStaticMember)
+// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember)
//
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C")
//
+// CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagStaticMember)
+//
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_a"
// CHECK-NOT: size:
// CHECK-NOT: align:
@@ -53,12 +69,6 @@ int C::a = 4;
// CHECK-SAME: flags: DIFlagStaticMember,
// CHECK-SAME: extraData: i1 true)
-// CHECK: ![[DECL_B:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
-// CHECK-NOT: size:
-// CHECK-NOT: align:
-// CHECK-NOT: offset:
-// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember)
-//
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_b"
// CHECK-NOT: size:
// CHECK-NOT: align:
@@ -82,9 +92,9 @@ int C::a = 4;
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a"
// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember)
-// CHECK: !DIGlobalVariable(name: "b", {{.*}}variable: i32* @_ZN1C1bE, declaration: ![[DECL_B]])
int C::b = 2;
-// CHECK: !DIGlobalVariable(name: "c", {{.*}}variable: i32* @_ZN1C1cE, declaration: ![[DECL_C]])
+// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]])
+// CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
int C::c = 1;
int main()
diff --git a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
index 08146c25263b..c8d8a1de855d 100644
--- a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
+++ b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
@@ -22,9 +22,6 @@ struct b {
};
extern template class b<int>;
b<int> bi;
-// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b<int>"
-// CHECK-NOT: DIFlagFwdDecl
-// CHECK-SAME: ){{$}}
template <typename T>
struct c {
@@ -116,3 +113,7 @@ template <>
struct k<int>;
template struct k<int>;
// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "k<int>"
+
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 88f024b59abf..2b840745ffeb 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// CHECK: @x = global %"struct.outer<foo>::inner" zeroinitializer, align 4, !dbg [[X:![0-9]+]]
+
struct MyClass {
template <int i> int add(int j) {
return i + j;
@@ -17,9 +19,9 @@ inline int add3(int x) {
}
// 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: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]])
+// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
+// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
// 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"
@@ -38,7 +40,7 @@ inline int add3(int x) {
// 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: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 9,
// CHECK: !DISubprogram(name: "add<2>"
// CHECK-SAME: scope: [[C]]
diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp
index 7a0d0d4a2755..cfee78d97493 100644
--- a/test/CodeGenCXX/debug-info-template-quals.cpp
+++ b/test/CodeGenCXX/debug-info-template-quals.cpp
@@ -17,10 +17,10 @@ void foo (const char *c) {
// 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: [[CH]] = !DIBasicType(name: "char", size: 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-SAME: size: 8
// CHECK: [[TYPE:![0-9]*]] = !DISubroutineType(types: [[ARGS:.*]])
// CHECK: [[ARGS]] = !{!{{.*}}, !{{.*}}, [[P]], [[R:.*]]}
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index d35bb70fa713..54fac0b36eec 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -1,5 +1,9 @@
// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s
+// CHECK: @tci = global %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]]
+// CHECK: @tcn = global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]]
+// CHECK: @nn = global %struct.NN zeroinitializer, align 1, !dbg [[NN:![0-9]+]]
+
// CHECK: !DICompileUnit(
// CHECK: [[EMPTY:![0-9]*]] = !{}
@@ -18,13 +22,12 @@ struct TC {
};
};
-// 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: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]])
+// CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci",
+// CHECK-SAME: type: ![[TCNESTED:[0-9]+]]
// CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
// CHECK-SAME: scope: ![[TC:[0-9]+]],
@@ -39,7 +42,8 @@ TC
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]]
+// CHECK: [[CINT]] = !DIDerivedType(tag: DW_TAG_const_type, {{.*}}baseType: [[INT:![0-9]+]]
+// CHECK: [[INT]] = !DIBasicType(name: "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: ![[FOO:[0-9]+]])
@@ -59,7 +63,7 @@ TC
// CHECK: [[FARG1]] = !DIDerivedType(tag: DW_TAG_pointer_type,
// CHECK-SAME: baseType: ![[FOO]]
// CHECK-NOT: line:
-// CHECK-SAME: size: 64, align: 64
+// CHECK-SAME: size: 64
// CHECK-NOT: offset: 0
// CHECK-SAME: DIFlagArtificial
// CHECK: [[FUNTYPE:![0-9]*]] = !DISubroutineType(types: [[FUNARGS:![0-9]*]])
@@ -80,9 +84,9 @@ TC
// CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3)
3>::nested tci;
-// CHECK: !DIGlobalVariable(name: "tcn"
-// CHECK-SAME: type: ![[TCNT:[0-9]+]]
-// CHECK-SAME: variable: %struct.TC* @tcn
+// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]])
+// CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn"
+// CHECK-SAME: type: ![[TCNT:[0-9]+]]
TC
// CHECK: ![[TCNT]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "TC<int, -3, nullptr, nullptr, nullptr, nullptr>"
// CHECK-SAME: templateParams: [[TCNARGS:![0-9]*]]
@@ -121,9 +125,9 @@ 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
+// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]])
+// CHECK: [[NNV]] = distinct !DIGlobalVariable(name: "nn"
+// CHECK-SAME: type: ![[NNT:[0-9]+]]
// FIXME: these parameters should probably be rendered as 'glb' rather than
// '&glb', since they're references, not pointers.
@@ -150,7 +154,7 @@ PaddingAtEnd 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)
+// CHECK: [[CONST_PADDINGATEND_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[PADDINGATEND]], size: 64)
template <PaddingAtEnd *>
struct PaddingAtEndTemplate {
};
diff --git a/test/CodeGenCXX/debug-info-thunk-msabi.cpp b/test/CodeGenCXX/debug-info-thunk-msabi.cpp
new file mode 100644
index 000000000000..5c705ac0ac13
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-thunk-msabi.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple i386-pc-windows-msvc19.0.0 -emit-llvm \
+// RUN: -debug-info-kind=line-tables-only -fms-extensions -o - | FileCheck %s
+class __declspec(dllexport) A {
+ A(int * = new int) {}
+};
+// CHECK: define {{.*}}void @"\01??_FA@@AAEXXZ"
+// CHECK-SAME: !dbg ![[SP:[0-9]+]]
+// CHECK-NOT: {{ret }}
+// CHECK: call x86_thiscallcc %class.A* @"\01??0A@@AAE@PAH@Z"
+// CHECK-SAME: !dbg ![[DBG:[0-9]+]]
+// CHECK: ret void, !dbg
+//
+// CHECK: ![[SP]] = distinct !DISubprogram(
+// CHECK-SAME: line: 4
+// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DIFlagArtificial
+// CHECK-SAME: ){{$}}
+//
+// CHECK: ![[DBG]] = !DILocation(line: 0
diff --git a/test/CodeGenCXX/debug-info-thunk.cpp b/test/CodeGenCXX/debug-info-thunk.cpp
index cd00ec937318..f7d16f493256 100644
--- a/test/CodeGenCXX/debug-info-thunk.cpp
+++ b/test/CodeGenCXX/debug-info-thunk.cpp
@@ -13,8 +13,17 @@ struct C : A, B {
};
void C::f() { }
-
-// CHECK: !DISubprogram(linkageName: "_ZThn{{[48]}}_N1C1fEv"
+// CHECK: define {{.*}}void @_ZThn{{[48]}}_N1C1fEv
+// CHECK-SAME: !dbg ![[SP:[0-9]+]]
+// CHECK-NOT: {{ret }}
+// CHECK: = load{{.*}} !dbg ![[DBG:[0-9]+]]
+// CHECK-NOT: {{ret }}
+// CHECK: ret void, !dbg ![[DBG]]
+//
+// CHECK: ![[SP]] = distinct !DISubprogram(linkageName: "_ZThn{{[48]}}_N1C1fEv"
// CHECK-SAME: line: 15
// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DIFlagArtificial
// CHECK-SAME: ){{$}}
+//
+// CHECK: ![[DBG]] = !DILocation(line: 0
diff --git a/test/CodeGenCXX/debug-info-union.cpp b/test/CodeGenCXX/debug-info-union.cpp
index 19e67418f9dc..cffe6e961cd4 100644
--- a/test/CodeGenCXX/debug-info-union.cpp
+++ b/test/CodeGenCXX/debug-info-union.cpp
@@ -12,7 +12,7 @@ E e;
// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "E"
// CHECK-SAME: line: 3
-// CHECK-SAME: size: 32, align: 32
+// CHECK-SAME: size: 32
// CHECK-NOT: offset:
// CHECK-SAME: {{$}}
// CHECK: !DISubprogram(name: "bb"{{.*}}, line: 6
diff --git a/test/CodeGenCXX/debug-info-uuid.cpp b/test/CodeGenCXX/debug-info-uuid.cpp
index a304f37078b6..70b205ad0993 100644
--- a/test/CodeGenCXX/debug-info-uuid.cpp
+++ b/test/CodeGenCXX/debug-info-uuid.cpp
@@ -1,6 +1,18 @@
// RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-pc-win32 -debug-info-kind=limited %s -o - -std=c++11 | FileCheck %s
// RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-unknown-unknown -debug-info-kind=limited %s -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=CHECK-ITANIUM
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>"
+// CHECK-SAME: templateParams: [[TGI2ARGS:![0-9]*]]
+// CHECK: [[TGI2ARGS]] = !{[[TGI2ARG1:![0-9]*]]}
+// CHECK: [[TGI2ARG1]] = !DITemplateValueParameter(
+// CHECK-SAME: type: [[CONST_GUID_REF:![0-9]*]]
+// CHECK-SAME: value: { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab
+// CHECK: [[CONST_GUID_REF]] = !DIDerivedType(tag: DW_TAG_reference_type,
+// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]]
+// CHECK: [[CONST_GUID]] = !DIDerivedType(tag: DW_TAG_const_type
+// CHECK-SAME: baseType: [[GUID:![0-9]*]]
+// CHECK: [[GUID]] = !DICompositeType(tag: DW_TAG_structure_type, name: "_GUID"
+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>"
// CHECK-SAME: templateParams: [[TGIARGS:![0-9]*]]
// CHECK: [[TGIARGS]] = !{[[TGIARG1:![0-9]*]]}
@@ -10,24 +22,11 @@
// CHECK: [[CONST_GUID_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type
// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]]
// CHECK-SAME: size: 64
-// CHECK-SAME: align: 64
-// CHECK: [[CONST_GUID]] = !DIDerivedType(tag: DW_TAG_const_type
-// CHECK-SAME: baseType: [[GUID:![0-9]*]]
-// CHECK: [[GUID]] = !DICompositeType(tag: DW_TAG_structure_type, name: "_GUID"
-
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>"
-// CHECK-SAME: templateParams: [[TGI2ARGS:![0-9]*]]
-// CHECK: [[TGI2ARGS]] = !{[[TGI2ARG1:![0-9]*]]}
-// CHECK: [[TGI2ARG1]] = !DITemplateValueParameter(
-// CHECK-SAME: type: [[CONST_GUID_REF:![0-9]*]]
-// CHECK-SAME: value: { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab
-// CHECK: [[CONST_GUID_REF]] = !DIDerivedType(tag: DW_TAG_reference_type,
-// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]]
-// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>"
-// CHECK-ITANIUM-SAME: identifier: "_ZTS9tmpl_guidIXadu8__uuidoft4uuidEE"
// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>"
// CHECK-ITANIUM-SAME: identifier: "_ZTS10tmpl_guid2IXu8__uuidoft4uuidEE"
+// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>"
+// CHECK-ITANIUM-SAME: identifier: "_ZTS9tmpl_guidIXadu8__uuidoft4uuidEE"
struct _GUID;
template <const _GUID *>
diff --git a/test/CodeGenCXX/debug-info-vla.cpp b/test/CodeGenCXX/debug-info-vla.cpp
new file mode 100644
index 000000000000..88f3a3f55dab
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-vla.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -target x86_64-unknown-unknown -fverbose-asm -g -O0 -S -emit-llvm %s -o - -std=c++11 | FileCheck %s
+
+
+void f(int m) {
+ int x[3][m];
+}
+
+int (*fp)(int[][*]) = nullptr;
+
+// CHECK: !DICompositeType(tag: DW_TAG_array_type,
+// CHECK-NOT: size:
+// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
+// CHECK: [[ELEM_TYPE]] = !{[[NOCOUNT:.*]]}
+// CHECK: [[NOCOUNT]] = !DISubrange(count: -1)
+//
+// CHECK: !DICompositeType(tag: DW_TAG_array_type,
+// CHECK-NOT: size:
+// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
+// CHECK: [[ELEM_TYPE]] = !{[[THREE:.*]], [[NOCOUNT]]}
+// CHECK: [[THREE]] = !DISubrange(count: 3)
diff --git a/test/CodeGenCXX/debug-info-windows-dtor.cpp b/test/CodeGenCXX/debug-info-windows-dtor.cpp
index e5a51abae68b..8eb744a61bc7 100644
--- a/test/CodeGenCXX/debug-info-windows-dtor.cpp
+++ b/test/CodeGenCXX/debug-info-windows-dtor.cpp
@@ -19,4 +19,4 @@ template struct AB<int>;
// CHECK: define
// CHECK: [[THUNK_VEC_DEL_DTOR]] = distinct !DISubprogram
-// CHECK: [[THUNK_LOC]] = !DILocation(line: 15, scope: [[THUNK_VEC_DEL_DTOR]])
+// CHECK: [[THUNK_LOC]] = !DILocation(line: 0, scope: [[THUNK_VEC_DEL_DTOR]])
diff --git a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
index dc7558aa3935..9f8eab624b40 100644
--- a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
+++ b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
@@ -10,7 +10,6 @@ A a;
// CHECK-SAME: baseType: [[ARRAY_TYPE:![0-9]+]]
// CHECK: [[ARRAY_TYPE]] = !DICompositeType(tag: DW_TAG_array_type,
// CHECK-NOT: size:
-// CHECK-SAME: align: 32
// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
// CHECK: [[ELEM_TYPE]] = !{[[SUBRANGE:.*]]}
// CHECK: [[SUBRANGE]] = !DISubrange(count: -1)
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 2e8d5fd5f137..9575a5129e3d 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -1,14 +1,16 @@
// 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: @_ZN6pr96081xE = global [3 x i8]* null, align 8, !dbg [[X:![0-9]+]]
+
// 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: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]])
+// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
+// CHECK-SAME: type: [[INCARRAYPTR:![0-9]*]]
// CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]]
// CHECK: [[INCARRAY]] = !DICompositeType(tag: DW_TAG_array_type
// CHECK-NOT: line:
@@ -67,8 +69,8 @@ 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,
+// MSVC-SAME: size: 96
+// CHECK-SAME: size: 128,
// BOTH-NOT: offset:
// BOTH-NOT: DIFlagFwdDecl
// BOTH-SAME: elements: [[VBASE_B_DEF:![0-9]+]]
diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp
index b01f770bdd97..1717fc468656 100644
--- a/test/CodeGenCXX/debug-lambda-expressions.cpp
+++ b/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -15,6 +15,12 @@ struct D { D(); D(const D&); int x; };
int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// Randomness for file. -- 6
+
+// VAR:
+// CHECK: !DIGlobalVariable(name: "var"
+// CHECK-SAME: line: [[VAR_LINE:[0-9]+]]
+// CHECK-SAME: type: ![[VAR_T:[0-9]+]]
+
// CHECK: [[FILE:.*]] = !DIFile(filename: "{{.*}}debug-lambda-expressions.cpp",
// CVAR:
@@ -26,10 +32,6 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// 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]+]]
diff --git a/test/CodeGenCXX/debug-lambda-this.cpp b/test/CodeGenCXX/debug-lambda-this.cpp
index 4af3d81983b2..eecbac6520ac 100644
--- a/test/CodeGenCXX/debug-lambda-this.cpp
+++ b/test/CodeGenCXX/debug-lambda-this.cpp
@@ -13,10 +13,10 @@ 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: ![[POINTER:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[D]], size: 64)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "this",
// CHECK-SAME: line: 11
// CHECK-SAME: baseType: ![[POINTER]]
-// CHECK-SAME: size: 64, align: 64
+// CHECK-SAME: size: 64
// CHECK-NOT: offset: 0
// CHECK-SAME: ){{$}}
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index 6a7f43a51287..f7b46818e39d 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
struct T {
T();
@@ -71,3 +71,10 @@ namespace test1 {
D d;
}
+
+namespace test2 {
+ // CHECK: define linkonce_odr void @_ZN5test21AIiED2Ev(
+ template <typename T> struct A { A() {} ~A() {} };
+ template <typename> void f(const A<int> & = {}) {}
+ void g() { f<int>(); }
+}
diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp
index c69b45630ef6..3bd5e35615ac 100644
--- a/test/CodeGenCXX/derived-to-base.cpp
+++ b/test/CodeGenCXX/derived-to-base.cpp
@@ -46,4 +46,4 @@ namespace test3 {
}
}
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index d6aabee58b9e..b082908b2c94 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -1,11 +1,16 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns > %t
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-passes -std=c++03 > %t
// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
// 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
+// RUN: FileCheck --check-prefixes=CHECK4,CHECK4v03 --input-file=%t %s
+// RUN: FileCheck --check-prefixes=CHECK5,CHECK5v03 --input-file=%t %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-passes -std=c++11 > %t2
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK2v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK4,CHECK4v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK5,CHECK5v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s
// REQUIRES: asserts
struct A {
@@ -98,6 +103,12 @@ namespace test0 {
// CHECK2: invoke void @_ZN5test04BaseD2Ev
// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+// In C++11, the destructors are often known not to throw.
+// CHECK2v11-LABEL: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
+// CHECK2v11-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+
struct B : Base, virtual VBase {
Member M;
~B();
@@ -111,6 +122,10 @@ namespace test0 {
// CHECK2: invoke void @_ZN5test04BaseD2Ev
// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK2v11-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+
// CHECK2-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
// CHECK2: invoke void @_ZN5test06MemberD1Ev
// CHECK2: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
@@ -118,6 +133,11 @@ namespace test0 {
// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
// CHECK2: invoke void @_ZN5test05VBaseD2Ev
// CHECK2: unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// CHECK2v11-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+// CHECK2v11: call void @_ZN5test05VBaseD2Ev
}
// Test base-class aliasing.
@@ -189,19 +209,22 @@ namespace test3 {
}
// CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
- // CHECK4: invoke void @_ZN5test31BD2Ev(
+ // CHECK4v03: invoke void @_ZN5test31BD2Ev(
+ // CHECK4v11: call void @_ZN5test31BD2Ev(
// CHECK4: call void @_ZN5test31AD2Ev(
// CHECK4: ret void
// CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr
- // CHECK4-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- // CHECK4: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+ // CHECK4v03-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK4v03: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+ // CHECK4v11: call void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
// CHECK4: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]]
// CHECK4: ret void
- // CHECK4: landingpad { i8*, i32 }
- // CHECK4-NEXT: cleanup
- // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
- // CHECK4: resume { i8*, i32 }
+ // CHECK4v03: landingpad { i8*, i32 }
+ // CHECK4v03-NEXT: cleanup
+ // CHECK4v03: call void @_ZdlPv({{.*}}) [[NUW]]
+ // CHECK4v03: resume { i8*, i32 }
+ // CHECK4v11-NOT: landingpad
// CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev(
// CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
@@ -214,14 +237,15 @@ namespace test3 {
// CHECK4: ret void
// CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
- // CHECK4-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- // CHECK4: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK4v03-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK4v03: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK4v11: call void @_ZN5test312_GLOBAL__N_11CD2Ev(
// CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
// CHECK4: ret void
- // CHECK4: landingpad { i8*, i32 }
- // CHECK4-NEXT: cleanup
- // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
- // CHECK4: resume { i8*, i32 }
+ // CHECK4v03: landingpad { i8*, i32 }
+ // CHECK4v03-NEXT: cleanup
+ // CHECK4v03: call void @_ZdlPv({{.*}}) [[NUW]]
+ // CHECK4v03: resume { i8*, i32 }
// CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
// CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
@@ -282,8 +306,8 @@ namespace test5 {
// CHECK5-LABEL: define void @_ZN5test53fooEv()
// CHECK5: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
- // CHECK5-NEXT: [[EXN:%.*]] = alloca i8*
- // CHECK5-NEXT: [[SEL:%.*]] = alloca i32
+ // CHECK5v03-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK5v03-NEXT: [[SEL:%.*]] = alloca i32
// CHECK5-NEXT: [[PELEMS:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to i8*
// CHECK5-NEXT: call void @llvm.lifetime.start(i64 5, i8* [[PELEMS]])
// CHECK5-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]], [5 x [[A]]]* [[ELEMS]], i32 0, i32 0
@@ -291,19 +315,22 @@ namespace test5 {
// CHECK5-NEXT: br label
// CHECK5: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
// CHECK5-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[POST]], i64 -1
- // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+ // CHECK5v03-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+ // CHECK5v11-NEXT: call void @_ZN5test51AD1Ev([[A]]* [[ELT]])
// CHECK5: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]
// CHECK5-NEXT: br i1 [[T0]],
// CHECK5: call void @llvm.lifetime.end
// CHECK5-NEXT: ret void
// lpad
- // CHECK5: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
- // CHECK5-NEXT: br i1 [[EMPTY]]
- // CHECK5: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
- // CHECK5-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
- // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
- // CHECK5: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
- // CHECK5-NEXT: br i1 [[DONE]],
+ // CHECK5v03: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
+ // CHECK5v03-NEXT: br i1 [[EMPTY]]
+ // CHECK5v03: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK5v03-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+ // CHECK5v03-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
+ // CHECK5v03: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK5v03-NEXT: br i1 [[DONE]],
+ // CHECK5v11-NOT: landingpad
+ // CHECK5v11: }
void foo() {
A elems[5];
}
@@ -334,25 +361,34 @@ namespace test6 {
C::~C() { opaque(); }
// CHECK5-LABEL: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr
// CHECK5: invoke void @_ZN5test66opaqueEv
- // CHECK5: invoke void @_ZN5test61AD1Ev
- // CHECK5: invoke void @_ZN5test61AD1Ev
- // CHECK5: invoke void @_ZN5test61AD1Ev
- // CHECK5: invoke void @_ZN5test61BILj1EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj1EED2Ev
+ // CHECK5v11: call void @_ZN5test61AD1Ev
+ // CHECK5v11: call void @_ZN5test61AD1Ev
+ // CHECK5v11: call void @_ZN5test61AD1Ev
+ // CHECK5v11: call void @_ZN5test61BILj1EED2Ev
// CHECK5: call void @_ZN5test61BILj0EED2Ev
// CHECK5: ret void
- // CHECK5: invoke void @_ZN5test61AD1Ev
- // CHECK5: invoke void @_ZN5test61AD1Ev
- // CHECK5: invoke void @_ZN5test61AD1Ev
- // CHECK5: invoke void @_ZN5test61BILj1EED2Ev
- // CHECK5: invoke void @_ZN5test61BILj0EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj1EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj0EED2Ev
// CHECK5-LABEL: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
- // CHECK5: invoke void @_ZN5test61CD2Ev
- // CHECK5: invoke void @_ZN5test61BILj3EED2Ev
- // CHECK5: call void @_ZN5test61BILj2EED2Ev
- // CHECK5: ret void
- // CHECK5: invoke void @_ZN5test61BILj3EED2Ev
- // CHECK5: invoke void @_ZN5test61BILj2EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61CD2Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj3EED2Ev
+ // CHECK5v03: call void @_ZN5test61BILj2EED2Ev
+ // CHECK5v03: ret void
+ // CHECK5v03: invoke void @_ZN5test61BILj3EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj2EED2Ev
+
+ // CHECK5v11: call void @_ZN5test61CD2Ev
+ // CHECK5v11: call void @_ZN5test61BILj3EED2Ev
+ // CHECK5v11: call void @_ZN5test61BILj2EED2Ev
+ // CHECK5v11: ret void
}
// PR 9197
@@ -369,7 +405,8 @@ namespace test7 {
// Verify that this doesn't get emitted as an alias
// CHECK5-LABEL: define void @_ZN5test71BD2Ev(
- // CHECK5: invoke void @_ZN5test71DD1Ev(
+ // CHECK5v03: invoke void @_ZN5test71DD1Ev(
+ // CHECK5v11: call void @_ZN5test71DD1Ev(
// CHECK5: call void @_ZN5test71AD2Ev(
B::~B() {}
}
@@ -394,7 +431,8 @@ namespace test8 {
// CHECK5: call void @_ZN5test81AC1Ev([[A]]* [[X]])
// CHECK5-NEXT: br label
// CHECK5: invoke void @_ZN5test81AC1Ev([[A]]* [[Y]])
- // CHECK5: invoke void @_ZN5test81AD1Ev([[A]]* [[Y]])
+ // CHECK5v03: invoke void @_ZN5test81AD1Ev([[A]]* [[Y]])
+ // CHECK5v11: call void @_ZN5test81AD1Ev([[A]]* [[Y]])
// CHECK5-NOT: switch
// CHECK5: invoke void @_ZN5test83dieEv()
// CHECK5: unreachable
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
index 193ee5f80406..b90620ab600f 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
@@ -225,3 +225,19 @@ namespace Test9 {
return -static_cast<RA&>(*x);
}
}
+
+namespace Test10 {
+ struct A {
+ virtual int f();
+ };
+
+ struct B : A {
+ int f() final;
+ };
+
+ // CHECK-LABEL: define i32 @_ZN6Test101fEPNS_1BE
+ int f(B *b) {
+ // CHECK: call i32 @_ZN6Test101B1fEv
+ return static_cast<A *>(b)->f();
+ }
+}
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index 911ddeedd236..b4c39f3fcff5 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -1,8 +1,11 @@
-// RUN: %clang_cc1 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
struct A {
virtual void f();
virtual void f_const() const;
+ virtual void g();
A h();
};
@@ -37,6 +40,64 @@ void f(A a, A *ap, A& ar) {
(a).f();
}
+struct D : A { virtual void g(); };
+struct XD { D d; };
+
+D gd();
+
+void fd(D d, XD xd, D *p) {
+ // CHECK: call void @_ZN1A1fEv(%struct.A*
+ d.f();
+
+ // CHECK: call void @_ZN1D1gEv(%struct.D*
+ d.g();
+
+ // CHECK: call void @_ZN1A1fEv
+ D().f();
+
+ // CHECK: call void @_ZN1D1gEv
+ D().g();
+
+ // CHECK: call void @_ZN1A1fEv
+ gd().f();
+
+ // CHECK: call void @_ZNK1A7f_constEv
+ d.f_const();
+
+ // CHECK: call void @_ZN1A1fEv
+ (d).f();
+
+ // CHECK: call void @_ZN1A1fEv
+ (true, d).f();
+
+ // CHECK: call void @_ZN1D1gEv
+ (true, d).g();
+
+ // CHECK: call void @_ZN1A1fEv
+ xd.d.f();
+
+ // CHECK: call void @_ZN1A1fEv
+ XD().d.f();
+
+ // CHECK: call void @_ZN1A1fEv
+ D XD::*mp;
+ (xd.*mp).f();
+
+ // CHECK: call void @_ZN1D1gEv
+ (xd.*mp).g();
+
+ // Can't devirtualize this; we have no guarantee that p points to a D here,
+ // due to the "single object is considered to be an array of one element"
+ // rule.
+ // CHECK: call void %
+ p[0].f();
+
+ // FIXME: We can devirtualize this, by C++1z [expr.add]/6 (if the array
+ // element type and the pointee type are not similar, behavior is undefined).
+ // CHECK: call void %
+ p[1].f();
+}
+
struct B {
virtual void f();
~B();
@@ -100,3 +161,37 @@ namespace test4 {
p->fish.eat();
}
}
+
+// Do not devirtualize to pure virtual function calls.
+namespace test5 {
+ struct X {
+ virtual void f() = 0;
+ };
+ struct Y {};
+ // CHECK-LABEL: define {{.*}} @_ZN5test51f
+ void f(Y &y, X Y::*p) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51X1fEv
+ // CHECK: call void %
+ (y.*p).f();
+ };
+
+ struct Z final {
+ virtual void f() = 0;
+ };
+ // CHECK-LABEL: define {{.*}} @_ZN5test51g
+ void g(Z &z) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51Z1fEv
+ // CHECK: call void %
+ z.f();
+ }
+
+ struct Q {
+ virtual void f() final = 0;
+ };
+ // CHECK-LABEL: define {{.*}} @_ZN5test51h
+ void h(Q &q) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51Q1fEv
+ // CHECK: call void %
+ q.f();
+ }
+}
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index 7cef7c2d127e..eb9ca79b7b40 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -1,5 +1,5 @@
-// 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 i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-passes -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-passes -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
@@ -612,9 +612,9 @@ void W::foo() {}
// Copy ctor:
// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z"
// vftable:
-// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)], comdat($"\01??_7W@@6B@")
-// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[W_VTABLE]], i32 0, i32 1)
-// G32-DAG: @_ZTV1W = dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
+// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)] }, comdat($"\01??_7W@@6B@")
+// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[W_VTABLE]], i32 0, i32 0, i32 1)
+// G32-DAG: @_ZTV1W = dllexport unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] }
struct __declspec(dllexport) X : public virtual W {};
// vbtable:
@@ -771,6 +771,13 @@ USEMEMFUNC(ExplicitInstantiationDeclExportedDefTemplate<int>, f);
// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ"
// G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv
+template <typename T> struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate { void f() {} };
+ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExplicitInstantiationDefExportedTemplateInstance;
+template class __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>, f);
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefExportedTemplateIiE1fEv
+
namespace { struct InternalLinkageType {}; }
struct __declspec(dllexport) PR23308 {
void f(InternalLinkageType*);
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index 1fed1bf0acf1..19d9e1dfe7b6 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -44,7 +44,7 @@ void useSpecials() {
}
// Used to force non-trivial special members.
-struct ForceNonTrivial {
+struct __declspec(dllimport) ForceNonTrivial {
ForceNonTrivial();
~ForceNonTrivial();
ForceNonTrivial(const ForceNonTrivial&);
diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp
index 4baee50fcff3..91e747ae1c15 100644
--- a/test/CodeGenCXX/dllimport-rtti.cpp
+++ b/test/CodeGenCXX/dllimport-rtti.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=MSVC
-// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=GNU
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=GNU
struct __declspec(dllimport) S {
virtual void f() {}
} s;
-// 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: [[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 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 aff240f28769..4ec14b72109f 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -2,8 +2,8 @@
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
// RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
-// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
-// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s
// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
@@ -347,6 +347,17 @@ __declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nul
// MO1-DAG: define available_externally dllimport i32* @"\01?ReferencingImportedDelete@@YAPAHXZ"
USE(ReferencingImportedNew)
USE(ReferencingImportedDelete)
+struct ClassWithDtor { ~ClassWithDtor() {} };
+struct __declspec(dllimport) ClassWithNonDllImportField { ClassWithDtor t; };
+struct __declspec(dllimport) ClassWithNonDllImportBase : public ClassWithDtor { };
+USECLASS(ClassWithNonDllImportField);
+USECLASS(ClassWithNonDllImportBase);
+// MO1-DAG: declare dllimport x86_thiscallcc void @"\01??1ClassWithNonDllImportBase@@QAE@XZ"(%struct.ClassWithNonDllImportBase*)
+// MO1-DAG: declare dllimport x86_thiscallcc void @"\01??1ClassWithNonDllImportField@@QAE@XZ"(%struct.ClassWithNonDllImportField*)
+struct ClassWithCtor { ClassWithCtor() {} };
+struct __declspec(dllimport) ClassWithNonDllImportFieldWithCtor { ClassWithCtor t; };
+USECLASS(ClassWithNonDllImportFieldWithCtor);
+// MO1-DAG: declare dllimport x86_thiscallcc %struct.ClassWithNonDllImportFieldWithCtor* @"\01??0ClassWithNonDllImportFieldWithCtor@@QAE@XZ"(%struct.ClassWithNonDllImportFieldWithCtor* returned)
// A dllimport function with a TLS variable must not be available_externally.
__declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; }
@@ -620,15 +631,15 @@ USEMEMFUNC(V, foo)
struct __declspec(dllimport) W { virtual void foo() {} };
USECLASS(W)
// vftable:
-// 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*)]
+// MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [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*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] }
struct __declspec(dllimport) KeyFuncClass {
constexpr KeyFuncClass() {}
virtual void foo();
};
extern constexpr KeyFuncClass keyFuncClassVar = {};
-// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
+// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x i8*] }
struct __declspec(dllimport) X : public virtual W {};
USECLASS(X)
@@ -658,7 +669,7 @@ namespace Vtordisp {
// Don't dllimport the vtordisp.
// MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
- class Base {
+ class __declspec(dllimport) Base {
virtual void f() {}
};
template <typename T>
@@ -734,7 +745,7 @@ namespace PR21355 {
// S::~S is a key function, so we would ordinarily emit a strong definition for
// the vtable. However, S is imported, so the vtable should be too.
- // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*]
+ // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant { [4 x i8*] }
}
namespace PR21366 {
@@ -756,7 +767,7 @@ namespace PR27319 {
};
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*]
+ // MO1-DAG: @"\01??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] }
}
// MS ignores DLL attributes on partial specializations.
diff --git a/test/CodeGenCXX/empty-classes.cpp b/test/CodeGenCXX/empty-classes.cpp
index e27a961e123a..5727d5918291 100644
--- a/test/CodeGenCXX/empty-classes.cpp
+++ b/test/CodeGenCXX/empty-classes.cpp
@@ -96,3 +96,24 @@ namespace rdar20621065 {
// Type checked at the top of the file.
B b;
};
+
+// This test used to crash when CGRecordLayout::getNonVirtualBaseLLVMFieldNo was called.
+namespace record_layout {
+struct X0 {
+ int x[0];
+};
+
+template<typename>
+struct X2 : X0 {
+};
+
+template<typename>
+struct X3 : X2<int> {
+ X3() : X2<int>() {}
+};
+
+
+void test0() {
+ X3<int>();
+}
+}
diff --git a/test/CodeGenCXX/enable_if.cpp b/test/CodeGenCXX/enable_if.cpp
index e17695b413b6..4e7707aaeed9 100644
--- a/test/CodeGenCXX/enable_if.cpp
+++ b/test/CodeGenCXX/enable_if.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu| FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s
// Test address-of overloading logic
int test5(int);
diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp
index 589bc2265760..7a11a1e50582 100644
--- a/test/CodeGenCXX/exceptions-seh.cpp
+++ b/test/CodeGenCXX/exceptions-seh.cpp
@@ -2,7 +2,7 @@
// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH
// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
-// RUN: -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \
+// RUN: -o - -mconstructor-aliases -O1 -disable-llvm-passes | \
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
extern "C" unsigned long _exception_code();
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 7e00d78e4834..fb5711878764 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,5 +1,5 @@
// 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-linux-gnu -std=c++1y -O3 -disable-llvm-passes -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.
diff --git a/test/CodeGenCXX/global-dtor-no-atexit.cpp b/test/CodeGenCXX/global-dtor-no-atexit.cpp
index 9860412b1bda..862194126ba8 100644
--- a/test/CodeGenCXX/global-dtor-no-atexit.cpp
+++ b/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -43,4 +43,4 @@ void func() {
static A a1, a2;
}
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index e806af9eacb4..291b43cac0a0 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -18,9 +18,6 @@ struct D { ~D(); };
// CHECK: @__dso_handle = external global i8
// CHECK: @c = global %struct.C zeroinitializer, align 8
-// It's okay if we ever implement the IR-generation optimization to remove this.
-// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8], [7 x i8]*
-
// PR6205: The casts should not require global initializers
// CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C"
// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C", %"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0)
@@ -171,6 +168,8 @@ namespace test7 {
const int b3 = B().n;
// CHECK-NOT: @_ZN5test7L2c1E
+ // CHECK: call void @llvm.memset{{.*}} @_ZN5test7L2c1E
+ // CHECK-NOT: @_ZN5test7L2c1E
// CHECK: @_ZN5test7L2c2E
// CHECK-NOT: @_ZN5test7L2c3E
// CHECK: @_ZN5test7L2c4E
@@ -205,8 +204,8 @@ namespace test7 {
// rdar://problem/8090834: this should be nounwind
// CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
-// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} }
// PR21811: attach the appropriate attribute to the global init function
// CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
-// CHECK-FP: attributes [[NUX]] = { nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} }
+// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} }
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
index d0224131c4da..3f8665aa3b4d 100644
--- a/test/CodeGenCXX/implicit-copy-constructor.cpp
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -48,12 +48,14 @@ void f(D d) {
// CHECK: call void @_ZN1BC2ERS_
// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 28}}
// CHECK: call void @_ZN1BC1ERS_
-// CHECK: br
-// CHECK: {{icmp ult.*, 2}}
-// CHECK: {{icmp ult.*, 3}}
+// CHECK: br label
// CHECK: call void @_ZN1AC1Ev
// CHECK: call void @_ZN1CC1ERS_1A
// CHECK: call void @_ZN1AD1Ev
+// CHECK: {{icmp eq.*, 3}}
+// CHECK: br i1
+// CHECK: {{icmp eq.*, 2}}
+// CHECK: br i1
// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 300}}
// CHECK: ret void
diff --git a/test/CodeGenCXX/init-invariant.cpp b/test/CodeGenCXX/init-invariant.cpp
index 71eb7dd73492..815287c8e116 100644
--- a/test/CodeGenCXX/init-invariant.cpp
+++ b/test/CodeGenCXX/init-invariant.cpp
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-O0
// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm %s -O1 -o - | FileCheck %s
-// Check that we add an llvm.invariant.start to mark when a global becomes
+// Check that we add an llvm.invariant.start.p0i8 to mark when a global becomes
// read-only. If globalopt can fold the initializer, it will then mark the
// variable as constant.
// Do not produce markers at -O0.
-// CHECK-O0-NOT: llvm.invariant.start
+// CHECK-O0-NOT: llvm.invariant.start.p0i8
struct A {
A();
@@ -42,19 +42,19 @@ void e() {
}
// CHECK: call void @_ZN1AC1Ev({{.*}}* nonnull @a)
-// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @a to i8*))
+// CHECK: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @a to i8*))
// CHECK: call void @_ZN1BC1Ev({{.*}}* nonnull @b)
-// CHECK-NOT: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @b to i8*))
+// CHECK-NOT: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @b to i8*))
// CHECK: call void @_ZN1CC1Ev({{.*}}* nonnull @c)
-// CHECK-NOT: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @c to i8*))
+// CHECK-NOT: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @c to i8*))
// CHECK: call i32 @_Z1fv(
// CHECK: store {{.*}}, i32* @d
-// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @d to i8*))
+// CHECK: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @d to i8*))
// CHECK-LABEL: define void @_Z1ev(
// CHECK: call void @_ZN1AC1Ev(%struct.A* nonnull @_ZZ1evE1a)
-// CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* {{.*}}bitcast ({{.*}} @_ZZ1evE1a to i8*))
+// CHECK: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* {{.*}}bitcast ({{.*}} @_ZZ1evE1a to i8*))
// CHECK-NOT: llvm.invariant.end
diff --git a/test/CodeGenCXX/inline-dllexport-member.cpp b/test/CodeGenCXX/inline-dllexport-member.cpp
index 2160f32e0b4f..66ef459bd80b 100644
--- a/test/CodeGenCXX/inline-dllexport-member.cpp
+++ b/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -1,11 +1,13 @@
// RUN: %clang_cc1 -triple i686-windows-win32 -fms-extensions -debug-info-kind=limited -emit-llvm %s -o - \
// RUN: | FileCheck %s
+// CHECK: @"\01?ui@s@@2IB" = weak_odr dllexport constant i32 0, comdat, align 4, !dbg [[UI:![0-9]+]]
+
struct __declspec(dllexport) s {
static const unsigned int ui = 0;
};
-// CHECK: ![[SCOPE:[0-9]+]] = distinct !DICompileUnit(
-// CHECK: !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE]],
-// CHECK-SAME: variable: i32* @"\01?ui@s@@2IB"
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]])
+// CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
+// CHECK: ![[SCOPE]] = distinct !DICompileUnit(
diff --git a/test/CodeGenCXX/inline-hint.cpp b/test/CodeGenCXX/inline-hint.cpp
index 9c14032f9f69..c4de751ba76e 100644
--- a/test/CodeGenCXX/inline-hint.cpp
+++ b/test/CodeGenCXX/inline-hint.cpp
@@ -1,6 +1,6 @@
-// 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
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-functions -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-hint-functions -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -fno-inline -emit-llvm -disable-llvm-passes -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 {
diff --git a/test/CodeGenCXX/invariant.group-for-vptrs.cpp b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
index ca737ee23fb4..5c763538088b 100644
--- a/test/CodeGenCXX/invariant.group-for-vptrs.cpp
+++ b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -emit-llvm %s -fstrict-vtable-pointers -O1 -o - -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -emit-llvm %s -fstrict-vtable-pointers -O1 -o - -disable-llvm-passes | FileCheck %s
struct A {
virtual void foo();
@@ -23,7 +23,7 @@ void testExternallyVisible() {
// CHECK: load {{.*}} !invariant.group ![[A_MD]]
a2->foo();
}
-// CHECK-LABEL: }
+// CHECK-LABEL: {{^}}}
namespace {
@@ -52,7 +52,7 @@ void testInternallyVisible(bool p) {
// Checking A::A()
// CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev(
// CHECK: store {{.*}}, !invariant.group ![[A_MD]]
-// CHECK-LABEL: }
+// CHECK-LABEL: {{^}}}
// Checking D::D()
// CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp
index f6aa16e51a97..028017c176ad 100644
--- a/test/CodeGenCXX/key-function-vtable.cpp
+++ b/test/CodeGenCXX/key-function-vtable.cpp
@@ -44,8 +44,8 @@ inline void X1::f() { }
void use_X1() { X1 x1; }
// CHECK-DAG: @_ZTV2X1 = linkonce_odr unnamed_addr constant
-// CHECK-DAG: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testa = unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp
index f59d360314e4..2c625daaf831 100644
--- a/test/CodeGenCXX/lambda-expressions.cpp
+++ b/test/CodeGenCXX/lambda-expressions.cpp
@@ -54,12 +54,14 @@ int c(int x) { return [&x]{return x;}(); }
// CHECK: ret i32
struct D { D(); D(const D&); int x; };
-int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
+int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
// CHECK-LABEL: define i32 @_Z1di
// CHECK: call void @_ZN1DC1Ev
-// CHECK: icmp ult i64 %{{.*}}, 10
+// CHECK: br label
// CHECK: call void @_ZN1DC1ERKS_
+// CHECK: icmp eq i64 %{{.*}}, 10
+// CHECK: br i1
// CHECK: call i32 @"_ZZ1diENK3$_4clEv"
// CHECK-LABEL: define internal i32 @"_ZZ1diENK3$_4clEv"
// CHECK: load i32, i32*
@@ -67,7 +69,7 @@ int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
// CHECK: ret i32
struct E { E(); E(const E&); ~E(); int x; };
-int e(E a, E b, bool cond) { [a,b,cond](){ return (cond ? a : b).x; }(); }
+int e(E a, E b, bool cond) { return [a,b,cond](){ return (cond ? a : b).x; }(); }
// CHECK-LABEL: define i32 @_Z1e1ES_b
// CHECK: call void @_ZN1EC1ERKS_
// CHECK: invoke void @_ZN1EC1ERKS_
@@ -116,6 +118,72 @@ int *PR22071_fun() {
return [&] { return &y; }();
}
+namespace pr28595 {
+ struct Temp {
+ Temp();
+ ~Temp() noexcept(false);
+ };
+ struct A {
+ A();
+ A(const A &a, const Temp &temp = Temp());
+ ~A();
+ };
+
+ void after_init() noexcept;
+
+ // CHECK-LABEL: define void @_ZN7pr285954testEv()
+ void test() {
+ // CHECK: %[[SRC:.*]] = alloca [3 x [5 x %[[A:.*]]]], align 1
+ A array[3][5];
+
+ // Skip over the initialization loop.
+ // CHECK: call {{.*}}after_init
+ after_init();
+
+ // CHECK: %[[DST_0:.*]] = getelementptr {{.*}} [3 x [5 x %[[A]]]]* %[[DST:.*]], i64 0, i64 0
+ // CHECK: br label
+ // CHECK: %[[I:.*]] = phi i64 [ 0, %{{.*}} ], [ %[[I_NEXT:.*]], {{.*}} ]
+ // CHECK: %[[DST_I:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[DST_0]], i64 %[[I]]
+ // CHECK: %[[SRC_I:.*]] = getelementptr {{.*}} [3 x [5 x %[[A]]]]* %[[SRC]], i64 0, i64 %[[I]]
+ //
+ // CHECK: %[[DST_I_0:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[DST_I]], i64 0, i64 0
+ // CHECK: br label
+ // CHECK: %[[J:.*]] = phi i64 [ 0, %{{.*}} ], [ %[[J_NEXT:.*]], {{.*}} ]
+ // CHECK: %[[DST_I_J:.*]] = getelementptr {{.*}} %[[A]]* %[[DST_I_0]], i64 %[[J]]
+ // CHECK: %[[DST_0_0:.*]] = bitcast [5 x %[[A]]]* %[[DST_0]] to %[[A]]*
+ // CHECK: %[[SRC_I_J:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[SRC_I]], i64 0, i64 %[[J]]
+ //
+ // CHECK: invoke void @_ZN7pr285954TempC1Ev
+ // CHECK: invoke void @_ZN7pr285951AC1ERKS0_RKNS_4TempE
+ // CHECK: invoke void @_ZN7pr285954TempD1Ev
+ //
+ // CHECK: add nuw i64 %[[J]], 1
+ // CHECK: icmp eq
+ // CHECK: br i1
+ //
+ // CHECK: add nuw i64 %[[I]], 1
+ // CHECK: icmp eq
+ // CHECK: br i1
+ //
+ // CHECK: ret void
+ //
+ // CHECK: landingpad
+ // CHECK: landingpad
+ // CHECK: br label %[[CLEANUP:.*]]{{$}}
+ // CHECK: landingpad
+ // CHECK: invoke void @_ZN7pr285954TempD1Ev
+ // CHECK: br label %[[CLEANUP]]
+ //
+ // CHECK: [[CLEANUP]]:
+ // CHECK: icmp eq %[[A]]* %[[DST_0_0]], %[[DST_I_J]]
+ // CHECK: %[[T0:.*]] = phi %[[A]]*
+ // CHECK: %[[T1:.*]] = getelementptr inbounds %[[A]], %[[A]]* %[[T0]], i64 -1
+ // CHECK: call void @_ZN7pr285951AD1Ev(%[[A]]* %[[T1]])
+ // CHECK: icmp eq %[[A]]* %[[T1]], %[[DST_0_0]]
+ (void) [array]{};
+ }
+}
+
// CHECK-LABEL: define internal void @"_ZZ1e1ES_bEN3$_5D2Ev"
// CHECK-LABEL: define internal i32 @"_ZZ1fvEN3$_68__invokeEii"
@@ -126,9 +194,9 @@ int *PR22071_fun() {
// CHECK-NEXT: call i32 @"_ZZ1fvENK3$_6clEii"
// CHECK-NEXT: ret i32
-// CHECK-LABEL: define internal void @"_ZZ1hvEN4$_108__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} {
+// CHECK-LABEL: define internal void @"_ZZ1hvEN4$_118__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} {
// CHECK-NOT: =
-// CHECK: call void @"_ZZ1hvENK4$_10clEv"(%struct.A* sret %agg.result,
+// CHECK: call void @"_ZZ1hvENK4$_11clEv"(%struct.A* sret %agg.result,
// CHECK-NEXT: ret void
struct A { ~A(); };
void h() {
diff --git a/test/CodeGenCXX/linkage.cpp b/test/CodeGenCXX/linkage.cpp
index 60e53c6444e2..69b426269ccd 100644
--- a/test/CodeGenCXX/linkage.cpp
+++ b/test/CodeGenCXX/linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-optzns %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-passes %s -o - | FileCheck %s
namespace test1 {
// CHECK-DAG: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_(
diff --git a/test/CodeGenCXX/main-norecurse.cpp b/test/CodeGenCXX/main-norecurse.cpp
index 0f3640260962..a98677ce6f59 100644
--- a/test/CodeGenCXX/main-norecurse.cpp
+++ b/test/CodeGenCXX/main-norecurse.cpp
@@ -5,4 +5,4 @@ int main(int argc, char **argv) {
return 1;
}
-// CHECK: attributes #0 = { norecurse{{.*}} }
+// CHECK: attributes #0 = { noinline norecurse{{.*}} }
diff --git a/test/CodeGenCXX/mangle-abi-tag.cpp b/test/CodeGenCXX/mangle-abi-tag.cpp
index 385a16f26a51..a653ff42228a 100644
--- a/test/CodeGenCXX/mangle-abi-tag.cpp
+++ b/test/CodeGenCXX/mangle-abi-tag.cpp
@@ -203,3 +203,32 @@ void f18_test() {
}
// A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice!
// CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv(
+
+namespace N19 {
+ class A {};
+ class __attribute__((abi_tag("B"))) B {};
+ class D {};
+ class F {};
+
+ template<typename T, B F(T, D)>
+ class C {};
+
+ B foo(A, D);
+}
+void f19_test(N19::C<N19::A, &N19::foo>, N19::F, N19::D) {
+}
+// f19_test(N19::C<N19::A, &N19::foo[abi:B]>, N19::F, N19::D)
+// CHECK-DAG: define void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_(
+
+namespace pr30440 {
+
+template<class F> void g(F);
+template<class ...A> auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
+}
+// CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIL_ZZNS_1hEDpT_E1aEEfp_EEES2_(
+
+void pr30440_test () {
+ h();
+}
+
+}
diff --git a/test/CodeGenCXX/mangle-exception-spec.cpp b/test/CodeGenCXX/mangle-exception-spec.cpp
new file mode 100644
index 000000000000..15f7a8b6cb50
--- /dev/null
+++ b/test/CodeGenCXX/mangle-exception-spec.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -Wno-dynamic-exception-spec | FileCheck %s --check-prefix CHECK --check-prefix CHECK-CXX11
+// RUN: %clang_cc1 -std=c++1z -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -Wno-dynamic-exception-spec | FileCheck %s --check-prefix CHECK --check-prefix CHECK-CXX17
+
+// CHECK: define {{.*}} @_Z1aPFivE(
+void a(int() throw(int, float)) {}
+// CHECK-CXX11: define {{.*}} @_Z1bPFivE(
+// CHECK-CXX17: define {{.*}} @_Z1bPDoFivE(
+void b(int() noexcept) {}
+// CHECK-CXX11: define {{.*}} @_Z1cPFivE(
+// CHECK-CXX17: define {{.*}} @_Z1cPDoFivE(
+void c(int() throw()) {}
+// CHECK: define {{.*}} @_Z1dPFivE(
+void d(int() noexcept(false)) {}
+// CHECK-CXX11: define {{.*}} @_Z1ePFivE(
+// CHECK-CXX17: define {{.*}} @_Z1ePDoFivE(
+void e(int() noexcept(true)) {}
+
+template<bool B> void f(int() noexcept(B)) {}
+// CHECK: define {{.*}} @_Z1fILb0EEvPDOT_EFivE(
+template void f<false>(int());
+// CHECK: define {{.*}} @_Z1fILb1EEvPDOT_EFivE(
+template void f<true>(int() noexcept);
+
+template<typename...T> void g(int() throw(T...)) {}
+// CHECK: define {{.*}} @_Z1gIJEEvPDwDpT_EFivE(
+template void g<>(int() noexcept);
+// CHECK: define {{.*}} @_Z1gIJfEEvPDwDpT_EFivE(
+template void g<float>(int());
+
+// We consider the exception specifications in parameter and return type here
+// to be different.
+template<typename...T> auto h(int() throw(int, T...)) -> int (*)() throw(T..., int) { return nullptr; }
+// CHECK: define {{.*}} @_Z1hIJEEPDwDpT_iEFivEPDwiS1_EFivE(
+template auto h<>(int()) -> int (*)();
+// CHECK: define {{.*}} @_Z1hIJfEEPDwDpT_iEFivEPDwiS1_EFivE(
+template auto h<float>(int()) -> int (*)();
+
+// FIXME: The C++11 manglings here are wrong; they should be the same as the
+// C++17 manglings.
+// The mangler mishandles substitutions for instantiation-dependent types that
+// differ only in type sugar that is not relevant for mangling. (In this case,
+// the types differ in presence/absence of ParenType nodes under the pointer.)
+template<typename...T> auto i(int() throw(int, T...)) -> int (*)() throw(int, T...) { return nullptr; }
+// CHECK-CXX11: define {{.*}} @_Z1iIJEEPDwiDpT_EFivEPS2_(
+// CHECK-CXX17: define {{.*}} @_Z1iIJEEPDwiDpT_EFivES3_(
+template auto i<>(int()) -> int (*)();
+// CHECK-CXX11: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivEPS2_(
+// CHECK-CXX17: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivES3_(
+template auto i<float>(int()) -> int (*)();
diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp
index 051cfdc3a221..15987ebe46bd 100644
--- a/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/test/CodeGenCXX/mangle-lambdas.cpp
@@ -173,6 +173,16 @@ namespace PR12123 {
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
+// CHECK-LABEL: define {{.*}} @_Z{{[0-9]*}}testVarargsLambdaNumberingv(
+inline int testVarargsLambdaNumbering() {
+ // CHECK: testVarargsLambdaNumberingvE{{.*}}UlzE_
+ auto a = [](...) { static int n; return ++n; };
+ // CHECK: testVarargsLambdaNumberingvE{{.*}}UlvE_
+ auto b = []() { static int n; return ++n; };
+ return a() + b();
+}
+int k = testVarargsLambdaNumbering();
+
// Check linkage of the various lambdas.
// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE_clEv
// CHECK: ret i32 1
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index 8e2577b03e26..819b0d9c9d0d 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -318,3 +318,32 @@ void unaligned_foo8_S::unaligned_foo8() volatile __unaligned {}
// CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
+namespace PR31197 {
+struct A {
+ // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R<lambda_1>@x@A@PR31197@@QBE@XZ"(
+ int *x = []() {
+ static int white;
+ // CHECK-DAG: @"\01?white@?1???R<lambda_1>@x@A@PR31197@@QBE@XZ@4HA"
+ return &white;
+ }();
+ // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R<lambda_1>@y@A@PR31197@@QBE@XZ"(
+ int *y = []() {
+ static int black;
+ // CHECK-DAG: @"\01?black@?1???R<lambda_1>@y@A@PR31197@@QBE@XZ@4HA"
+ return &black;
+ }();
+ using FPtrTy = void(void);
+ static void default_args(FPtrTy x = [] {}, FPtrTy y = [] {}, int z = [] { return 1; }() + [] { return 2; }()) {}
+ // CHECK-DAG: @"\01??R<lambda_1_1>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+ // CHECK-DAG: @"\01??R<lambda_1_2>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+ // CHECK-DAG: @"\01??R<lambda_2_1>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+ // CHECK-DAG: @"\01??R<lambda_3_1>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+};
+A a;
+
+int call_it = (A::default_args(), 1);
+}
+
+enum { enumerator };
+void f(decltype(enumerator)) {}
+// CHECK-DAG: define void @"\01?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp
index a62bdd5393c4..43b7bd79537d 100644
--- a/test/CodeGenCXX/mangle-unnamed.cpp
+++ b/test/CodeGenCXX/mangle-unnamed.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
struct S {
virtual ~S() { }
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 5d757102ed25..3a94071294d3 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1111,3 +1111,17 @@ void fn(T, __underlying_type(T)) {}
template void fn<E>(E, __underlying_type(E));
// CHECK-LABEL: @_ZN6test552fnINS_1EEEEvT_U3eutS2_
}
+
+namespace test56 {
+ struct A { A *operator->(); int n; } a;
+ template<int N> void f(decltype(a->n + N)) {}
+ // CHECK-LABEL: @_ZN6test561fILi0EEEvDTplptL_ZNS_1aEE1nT_E
+ template void f<0>(int);
+}
+
+namespace test57 {
+ struct X { template <int N> int f(); } x;
+ template<int N> void f(decltype(x.f<0>() + N)) {}
+ // CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fIXLi0EEEET_E
+ template void f<0>(int);
+}
diff --git a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
index 9ef1879ce5f2..146a6c8eda06 100644
--- a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
+++ b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -68,4 +68,4 @@ struct S {
void delete_s(S *s) { delete[] s; }
}
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
index 319f39c3ff48..6972dacd774f 100644
--- a/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
@@ -7,7 +7,7 @@ struct A {
};
A a(42);
-// CHECK: @"\01?a@@3UA@@A" = global { [1 x i8*]*, i32 } { [1 x i8*]* @"\01??_7A@@6B@", i32 42 }, align 4
+// CHECK: @"\01?a@@3UA@@A" = global { { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"\01??_7A@@6B@", i32 42 }, align 4
struct B {
constexpr B(int y) : y(y) {}
@@ -20,4 +20,4 @@ struct C : A, B {
};
C c;
-// CHECK: @"\01?c@@3UC@@A" = global { [1 x i8*]*, i32, [1 x i8*]*, i32 } { [1 x i8*]* @"\01??_7C@@6BA@@@", i32 777, [1 x i8*]* @"\01??_7C@@6BB@@@", i32 13 }
+// CHECK: @"\01?c@@3UC@@A" = global { { [1 x i8*] }*, i32, { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"\01??_7C@@6BA@@@", i32 777, { [1 x i8*] }* @"\01??_7C@@6BB@@@", i32 13 }
diff --git a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
index ac1321efeae2..6e18b92e0f41 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
// RUN: -mconstructor-aliases -fexceptions -fcxx-exceptions \
-// RUN: -O1 -disable-llvm-optzns \
+// RUN: -O1 -disable-llvm-passes \
// RUN: | FileCheck -check-prefix WIN64 %s
extern "C" void might_throw();
diff --git a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
index 004dc45652e4..79ac1e12173b 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -1,5 +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 -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
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-passes %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();
@@ -278,3 +278,38 @@ void f() {
// WIN32-LIFETIME: %[[bc2:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8*
// WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc2]])
}
+
+struct class_2 {
+ class_2();
+ virtual ~class_2();
+};
+struct class_1 : virtual class_2 {
+ class_1(){throw "Unhandled exception";}
+ virtual ~class_1() {}
+};
+struct class_0 : class_1 {
+ class_0() ;
+ virtual ~class_0() {}
+};
+
+class_0::class_0() {
+ // WIN32: define x86_thiscallcc %struct.class_0* @"\01??0class_0@@QAE@XZ"(%struct.class_0* returned %this, i32 %is_most_derived)
+ // WIN32: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // WIN32: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // WIN32: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // WIN32: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+ // WIN32: [[INIT_VBASES]]
+ // WIN32: br label %[[SKIP_VBASES]]
+ // WIN32: [[SKIP_VBASES]]
+// ehcleanup:
+ // WIN32: %[[CLEANUPPAD:.*]] = cleanuppad within none []
+ // WIN32-NEXT: bitcast %{{.*}}* %{{.*}} to i8*
+ // WIN32-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i{{.*}} {{.}}
+ // WIN32-NEXT: bitcast i8* %{{.*}} to %{{.*}}*
+ // WIN32-NEXT: %[[SHOULD_CALL_VBASE_DTOR:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // WIN32-NEXT: br i1 %[[SHOULD_CALL_VBASE_DTOR]], label %[[DTOR_VBASE:.*]], label %[[SKIP_VBASE:.*]]
+ // WIN32: [[DTOR_VBASE]]
+ // WIN32-NEXT: call x86_thiscallcc void @"\01??1class_2@@UAE@XZ"
+ // WIN32: br label %[[SKIP_VBASE]]
+ // WIN32: [[SKIP_VBASE]]
+}
diff --git a/test/CodeGenCXX/microsoft-abi-extern-template.cpp b/test/CodeGenCXX/microsoft-abi-extern-template.cpp
index de46d5b5c37c..c69b4f5b8d86 100644
--- a/test/CodeGenCXX/microsoft-abi-extern-template.cpp
+++ b/test/CodeGenCXX/microsoft-abi-extern-template.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -fno-rtti-data -O1 -disable-llvm-optzns %s -emit-llvm -o - -triple x86_64-windows-msvc | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti-data -O1 -disable-llvm-passes %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: @"\01??_7?$Foo@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [
// CHECK-SAME: i8* bitcast (i8* (%struct.Foo*, i32)* @"\01??_G?$Foo@H@@UEAAPEAXI@Z" to i8*)
-// CHECK-SAME: ], comdat
+// 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* %{{.*}})
diff --git a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
index 34cb85ec28d1..f9db2680e336 100644
--- a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -150,35 +150,35 @@ void emit_ctors() {
Left l;
// CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
// CHECK-NOT: getelementptr
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Left@@6B@" to i32 (...)**)
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Left@@6B@" to i32 (...)**)
// CHECK: ret
Right r;
// CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
// CHECK-NOT: getelementptr
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Right@@6B@" to i32 (...)**)
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Right@@6B@" to i32 (...)**)
// CHECK: ret
ChildOverride co;
// CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
// CHECK: ret
GrandchildOverride gc;
// CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
// CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
// CHECK: ret
}
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index f7dc52406740..7eea41c8712e 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
struct Empty {};
@@ -92,6 +93,9 @@ SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); }
// LINUX-LABEL: define void @_Z22small_with_ctor_returnv(%struct.SmallWithCtor* noalias sret %agg.result)
// WIN32: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
// WIN64: define void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+// FIXME: The 'sret' mark here doesn't seem to be enough to convince LLVM to
+// preserve the hidden sret pointer in R0 across the function.
+// WOA: define arm_aapcs_vfpcc void @"\01?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); }
// LINUX-LABEL: define void @_Z25small_with_vftable_returnv(%struct.SmallWithVftable* noalias sret %agg.result)
@@ -102,6 +106,7 @@ MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor();
// LINUX-LABEL: define void @_Z28medium_with_copy_ctor_returnv(%struct.MediumWithCopyCtor* noalias sret %agg.result)
// WIN32: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
// WIN64: define void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WOA: define arm_aapcs_vfpcc void @"\01?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
// Returning a large struct that doesn't fit into a register.
Big big_return() { return Big(); }
@@ -114,22 +119,26 @@ void small_arg(Small s) {}
// LINUX-LABEL: define void @_Z9small_arg5Small(i32 %s.0)
// WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.0)
// WIN64: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?small_arg@@YAXUSmall@@@Z"([1 x 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"(i32 %s.0, i32 %s.1)
// WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?medium_arg@@YAXUMedium@@@Z"([2 x i32] %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"(i32 %s.0)
// WIN64: define void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce)
+// WOA: define arm_aapcs_vfpcc void @"\01?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"([1 x 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)
+// WOA: define arm_aapcs_vfpcc void @"\01?multibyte_arg@@YAXUMultibyte@@@Z"([1 x i32] %s.coerce)
void packed_arg(Packed s) {}
// LINUX-LABEL: define void @_Z10packed_arg6Packed(%struct.Packed* byval align 4 %s)
@@ -145,6 +154,11 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WIN64: call void @"\01??1SmallWithDtor@@QEAA@XZ"
// WIN64: }
+// FIXME: MSVC incompatible!
+// WOA: define arm_aapcs_vfpcc void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
+// WOA: call arm_aapcs_vfpcc void @"\01??1SmallWithDtor@@QAA@XZ"(%struct.SmallWithDtor* %s)
+// WOA: }
+
void call_small_arg_with_dtor() {
small_arg_with_dtor(SmallWithDtor());
}
@@ -211,6 +225,7 @@ void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
// LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
// WIN32: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
// WIN64: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA: define arm_aapcs_vfpcc void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
void big_arg(Big s) {}
// LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
@@ -386,3 +401,30 @@ void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); };
// WIN32: %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]*
// WIN32: store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4
// WIN32: call void @"\01?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]])
+
+namespace pr30293 {
+// Virtual methods living in a secondary vtable take i8* as their 'this'
+// parameter because the 'this' parameter on entry points to the secondary
+// vptr. We used to have a bug where we didn't apply this rule consistently,
+// and it would cause assertion failures when used with inalloca.
+struct A {
+ virtual void f();
+};
+struct B {
+ virtual void __cdecl h(SmallWithDtor);
+};
+struct C final : A, B {
+ void g();
+ void __cdecl h(SmallWithDtor);
+ void f();
+};
+void C::g() { return h(SmallWithDtor()); }
+
+// WIN32-LABEL: define x86_thiscallcc void @"\01?g@C@pr30293@@QAEXXZ"(%"struct.pr30293::C"* %this)
+// WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"\01??0SmallWithDtor@@QAE@XZ"
+// WIN32: call void @"\01?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca %{{[^,)]*}})
+// WIN32: declare void @"\01?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca)
+
+// WIN64-LABEL: define void @"\01?g@C@pr30293@@QEAAXXZ"(%"struct.pr30293::C"* %this)
+// WIN64: declare void @"\01?h@C@pr30293@@UEAAXUSmallWithDtor@@@Z"(i8*, i32)
+}
diff --git a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
index 08df374f2fc9..4eb757af3f8b 100644
--- a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s
namespace test1 {
template <typename T> class A {
diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp
index a576f0c3d7e3..6397eeb7313f 100644
--- a/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -77,7 +77,7 @@ void check_vftable_offset() {
C c;
// The vftable pointer should point at the beginning of the vftable.
// CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to i32 (...)***
-// CHECK: store i32 (...)** bitcast ([2 x i8*]* @"\01??_7C@basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
+// CHECK: store i32 (...)** bitcast ({ [2 x i8*] }* @"\01??_7C@basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
}
void call_complete_dtor(C *obj_ptr) {
@@ -196,7 +196,7 @@ struct E : virtual C { int e; };
struct F : D, E { ~F(); int f; };
F::~F() {
-// CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*)
+// CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*{{[^,]*}})
// Do an adjustment from C vbase subobject to F as though F was the
// complete type.
// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 -20
diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp
index 0c9b58bbb4d4..968955f4ee1b 100644
--- a/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=NO-RTTI
-// RUN: %clang_cc1 %s -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=RTTI
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s -check-prefix=NO-RTTI
+// RUN: %clang_cc1 %s -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s -check-prefix=RTTI
// RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
// RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
@@ -8,38 +8,38 @@ struct S {
virtual ~S();
} s;
-// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4S@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat($"\01??_7S@@6B@")
-// RTTI-DAG: @"\01??_7S@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_S]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4S@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] }, comdat($"\01??_7S@@6B@")
+// RTTI-DAG: @"\01??_7S@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_S]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)]
+// NO-RTTI-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] }
struct __declspec(dllimport) U {
virtual ~U();
} u;
-// 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)
+// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant { [2 x i8*] } { [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 0, i32 1)
-// NO-RTTI-DAG: @"\01??_SU@@6B@" = linkonce_odr 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*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)] }
struct __declspec(dllexport) V {
virtual ~V();
} v;
-// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4V@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)], comdat($"\01??_7V@@6B@")
-// RTTI-DAG: @"\01??_7V@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_V]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4V@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)] }, comdat($"\01??_7V@@6B@")
+// RTTI-DAG: @"\01??_7V@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_V]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"\01??_7V@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)]
+// NO-RTTI-DAG: @"\01??_7V@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)] }
namespace {
struct W {
virtual ~W() {}
} w;
}
-// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
-// RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_W]], i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)] }
+// RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
+// NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)] }
struct X {};
template <class> struct Y : virtual X {
@@ -49,7 +49,7 @@ template <class> struct Y : virtual X {
extern template class Y<int>;
template Y<int>::Y();
-// 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)
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x i8*] } { [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 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
+// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [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 480ae8cfbbec..416aefa6b715 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -33,7 +33,7 @@ B::B() {
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
// Initialize vtorDisp:
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -66,7 +66,7 @@ B::~B() {
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
// Initialize vtorDisp:
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -245,9 +245,9 @@ struct D : virtual A, virtual B, virtual C {
D::D() {
// CHECK-LABEL: define x86_thiscallcc %"struct.multiple_vbases::D"* @"\01??0D@multiple_vbases@@QAE@XZ"
// Just make sure we emit 3 vtordisps after initializing vfptrs.
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
// ...
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
@@ -283,7 +283,7 @@ struct D : virtual Z, B, C {
} d;
D::~D() {
- // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*)
+ // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}})
// CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8*
// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24
// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"*
@@ -397,7 +397,7 @@ C::~C() {
// CHECK-NOT: getelementptr
// CHECK-NOT: bitcast
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
foo(this);
// CHECK: ret
@@ -432,7 +432,7 @@ E::~E() {
// CHECK-NOT: getelementptr
// CHECK-NOT: bitcast
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
- // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
foo(this);
}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
index aaee39c51db6..b97c432f5e02 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
@@ -177,3 +177,26 @@ void fop(C &c) {
}
}
+
+namespace pr30293 {
+struct NonTrivial {
+ ~NonTrivial();
+ int x;
+};
+struct A { virtual void f(); };
+struct B { virtual void __cdecl g(NonTrivial); };
+struct C final : A, B {
+ void f() override;
+ void __cdecl g(NonTrivial) override;
+};
+C *whatsthis;
+void C::f() { g(NonTrivial()); }
+void C::g(NonTrivial o) {
+ whatsthis = this;
+}
+
+// BITCODE-LABEL: define void @"\01?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca)
+// BITCODE: %[[this1:[^ ]*]] = load i8*, i8** %[[thisaddr:[^ ]*]], align 4
+// BITCODE-NEXT: %[[this2:[^ ]*]] = getelementptr inbounds i8, i8* %[[this1]], i32 -4
+// BITCODE-NEXT: store i8* %[[this2]], i8** %[[thisaddr]], align 4
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
index d22344840c19..2bf7da58ea9c 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -26,7 +26,7 @@ J::J() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test1::C *'): 0 non-virtual]
// VFTABLES-NEXT: 2 | test1::D *test1::J::foo()
-// GLOBALS-LABEL: @"\01??_7J@test1@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+// GLOBALS-LABEL: @"\01??_7J@test1@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
// GLOBALS: @"\01?foo@J@test1@@QAEPAUB@2@XZ"
// GLOBALS: @"\01?foo@J@test1@@QAEPAUC@2@XZ"
// GLOBALS: @"\01?foo@J@test1@@UAEPAUD@2@XZ"
@@ -44,7 +44,7 @@ K::K() {}
// Only B to C requires adjustment, but we get 3 thunks in K's vftable, two of
// which are trivial.
-// GLOBALS-LABEL: @"\01??_7K@test1@@6B@" = linkonce_odr unnamed_addr constant [4 x i8*]
+// GLOBALS-LABEL: @"\01??_7K@test1@@6B@" = linkonce_odr unnamed_addr constant { [4 x i8*] }
// GLOBALS: @"\01?foo@K@test1@@QAEPAUB@2@XZ"
// GLOBALS: @"\01?foo@K@test1@@QAEPAUC@2@XZ"
// GLOBALS: @"\01?foo@K@test1@@QAEPAUD@2@XZ"
@@ -90,7 +90,7 @@ J::J() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
// VFTABLES-NEXT: 1 | test2::D *test2::J::foo()
-// GLOBALS-LABEL: @"\01??_7J@test2@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7J@test2@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
K::K() {}
@@ -101,7 +101,7 @@ K::K() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test2::D *'): 0 non-virtual]
// VFTABLES-NEXT: 2 | test2::E *test2::K::foo()
-// GLOBALS-LABEL: @"\01??_7K@test2@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+// GLOBALS-LABEL: @"\01??_7K@test2@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
}
@@ -124,7 +124,7 @@ struct C : virtual A, B {
C::C() {}
-// GLOBALS-LABEL: @"\01??_7C@pr20479@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7C@pr20479@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
// GLOBALS: @"\01?f@B@pr20479@@QAEPAUA@2@XZ"
// GLOBALS: @"\01?f@B@pr20479@@UAEPAU12@XZ"
}
@@ -151,7 +151,7 @@ struct C : virtual A, virtual B {
C::C() {}
-// GLOBALS-LABEL: @"\01??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
// GLOBALS: @"\01?f@B@pr21073@@WPPPPPPPI@AEPAUA@2@XZ"
// GLOBALS: @"\01?f@B@pr21073@@WPPPPPPPI@AEPAU12@XZ"
}
@@ -168,7 +168,7 @@ D::D() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073_2::A *'): vbase #1, 0 non-virtual]
// VFTABLES-NEXT: 1 | pr21073_2::C *pr21073_2::C::foo()
-// GLOBALS-LABEL: @"\01??_7D@pr21073_2@@6B@" = {{.*}} constant [2 x i8*]
+// GLOBALS-LABEL: @"\01??_7D@pr21073_2@@6B@" = {{.*}} constant { [2 x i8*] }
// GLOBALS: @"\01?foo@C@pr21073_2@@QAEPAUA@2@XZ"
// GLOBALS: @"\01?foo@C@pr21073_2@@UAEPAU12@XZ"
}
@@ -196,7 +196,7 @@ D::D() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test3::D *'): 0 non-virtual]
// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
-// GLOBALS-LABEL: @"\01??_7D@test3@@6B@" = {{.*}} constant [3 x i8*]
+// GLOBALS-LABEL: @"\01??_7D@test3@@6B@" = {{.*}} constant { [3 x i8*] }
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUA@2@XZ"
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUB@2@XZ"
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAU12@XZ"
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
index aa39d6de615a..738c15d89d21 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -19,7 +19,7 @@ struct A {
int ia;
};
A a;
-// EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
void use(A *obj) { obj->f(); }
struct B : A {
@@ -39,7 +39,7 @@ struct B : A {
virtual void j();
};
B b;
-// EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant { [5 x i8*] }
void use(B *obj) { obj->f(); }
struct C {
@@ -69,7 +69,7 @@ struct D {
virtual ~D();
};
D d;
-// EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
void use(D *obj) { obj->f(); }
struct E : A {
@@ -107,7 +107,7 @@ struct F : A {
virtual ~F();
};
F f;
-// EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+// EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant { [5 x i8*] }
void use(F *obj) { obj->i(); }
struct G : E {
@@ -295,7 +295,7 @@ struct S {
// CHECK-NEXT: 0 | void S::f() [deleted]
virtual void f() = delete;
S();
- // EMITS-VFTABLE-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)]
+ // EMITS-VFTABLE-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] }
};
S::S() {}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index 83f8114bae99..342a584182cc 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -771,7 +771,7 @@ struct A {
};
struct __declspec(dllexport) B : virtual A {
virtual void f() = 0;
- // MANGLING-DAG: @"\01??_7B@Test13@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)]
+ // MANGLING-DAG: @"\01??_7B@Test13@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] }
};
}
@@ -788,8 +788,8 @@ C::C() {}
// CHECK-LABEL: VFTable for 'pr21031_1::B' in 'pr21031_1::C' (1 entry)
// CHECK-NEXT: 0 | void pr21031_1::B::g()
-// MANGLING-DAG: @"\01??_7C@pr21031_1@@6BB@1@@" = {{.*}} constant [1 x i8*]
-// MANGLING-DAG: @"\01??_7C@pr21031_1@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7C@pr21031_1@@6BB@1@@" = {{.*}} constant { [1 x i8*] }
+// MANGLING-DAG: @"\01??_7C@pr21031_1@@6B@" = {{.*}} constant { [1 x i8*] }
}
namespace pr21031_2 {
@@ -804,8 +804,8 @@ C::C() {}
// CHECK-LABEL: VFTable for 'pr21031_2::A' in 'pr21031_2::B' in 'pr21031_2::C' (1 entry)
// CHECK-NEXT: 0 | void pr21031_2::A::f()
-// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BA@1@@" = {{.*}} constant [1 x i8*]
-// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BB@1@@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BA@1@@" = {{.*}} constant { [1 x i8*] }
+// MANGLING-DAG: @"\01??_7C@pr21031_2@@6BB@1@@" = {{.*}} constant { [1 x i8*] }
}
namespace pr21062_1 {
@@ -818,7 +818,7 @@ D::D() {}
// CHECK-LABEL: VFTable for 'pr21062_1::A' in 'pr21062_1::D' (1 entry)
// CHECK-NEXT: 0 | void pr21062_1::A::f()
-// MANGLING-DAG: @"\01??_7D@pr21062_1@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7D@pr21062_1@@6B@" = {{.*}} constant { [1 x i8*] }
}
namespace pr21062_2 {
@@ -831,7 +831,7 @@ D::D() {}
// CHECK-LABEL: VFTable for 'pr21062_2::A' in 'pr21062_2::D' (1 entry)
// CHECK-NEXT: 0 | void pr21062_2::A::f()
-// MANGLING-DAG: @"\01??_7D@pr21062_2@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7D@pr21062_2@@6B@" = {{.*}} constant { [1 x i8*] }
}
namespace pr21064 {
@@ -843,5 +843,5 @@ D::D() {}
// CHECK-LABEL: VFTable for 'pr21064::B' in 'pr21064::C' in 'pr21064::D' (1 entry)
// CHECK-NEXT: 0 | void pr21064::B::f()
-// MANGLING-DAG: @"\01??_7D@pr21064@@6B@" = {{.*}} constant [1 x i8*]
+// MANGLING-DAG: @"\01??_7D@pr21064@@6B@" = {{.*}} constant { [1 x i8*] }
}
diff --git a/test/CodeGenCXX/microsoft-interface.cpp b/test/CodeGenCXX/microsoft-interface.cpp
index 8f4670a6946a..5f3a94a494b7 100644
--- a/test/CodeGenCXX/microsoft-interface.cpp
+++ b/test/CodeGenCXX/microsoft-interface.cpp
@@ -17,7 +17,7 @@ int fn() {
return s.test();
}
-// CHECK: @_ZTV1S = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)]
+// CHECK: @_ZTV1S = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)] }
// CHECK-LABEL: define i32 @_Z2fnv()
// CHECK: call x86_thiscallcc void @_ZN1SC1Ev(%struct.S* %s)
@@ -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, i32 0, i32 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, inrange 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, i32 0, i32 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, inrange 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-no-rtti-data.cpp b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
index 68fdf0586c0d..05255909ced3 100644
--- a/test/CodeGenCXX/microsoft-no-rtti-data.cpp
+++ b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
@@ -2,7 +2,7 @@
// vftable shouldn't have RTTI data in it.
// CHECK-NOT: @"\01??_R4S@@6B@"
-// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat
+// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] }, comdat
struct type_info;
namespace std { using ::type_info; }
diff --git a/test/CodeGenCXX/microsoft-uuidof.cpp b/test/CodeGenCXX/microsoft-uuidof.cpp
index 62e4b880ad46..9b4ff68d9aa8 100644
--- a/test/CodeGenCXX/microsoft-uuidof.cpp
+++ b/test/CodeGenCXX/microsoft-uuidof.cpp
@@ -1,4 +1,5 @@
// 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 - -DDEFINE_GUID -DBRACKET_ATTRIB -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
@@ -17,10 +18,17 @@ struct _GUID {
#endif
typedef struct _GUID GUID;
+#ifdef BRACKET_ATTRIB
+[uuid(12345678-1234-1234-1234-1234567890aB)] struct S1 { } s1;
+[uuid(87654321-4321-4321-4321-ba0987654321)] struct S2 { };
+[uuid({12345678-1234-1234-1234-1234567890ac})] struct Curly;
+[uuid({12345678-1234-1234-1234-1234567890ac})] struct Curly;
+#else
struct __declspec(uuid("12345678-1234-1234-1234-1234567890aB")) S1 { } s1;
struct __declspec(uuid("87654321-4321-4321-4321-ba0987654321")) S2 { };
struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly;
struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly;
+#endif
#ifdef DEFINE_GUID
// Make sure we can properly generate code when the UUID has curly braces on it.
diff --git a/test/CodeGenCXX/modules-ts.cppm b/test/CodeGenCXX/modules-ts.cppm
new file mode 100644
index 000000000000..da3bcb2174a7
--- /dev/null
+++ b/test/CodeGenCXX/modules-ts.cppm
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fmodules-ts -std=c++1z -triple=x86_64-linux-gnu -emit-module-interface %s -o %t.pcm
+// RUN: %clang_cc1 -fmodules-ts -std=c++1z -triple=x86_64-linux-gnu %t.pcm -emit-llvm -o - | FileCheck %s
+
+module FooBar;
+
+export {
+ // CHECK-LABEL: define i32 @_Z1fv(
+ int f() { return 0; }
+}
+
+// FIXME: Emit global variables and their initializers with this TU.
+// Emit an initialization function that other TUs can call, with guard variable.
+
+// FIXME: Mangle non-exported symbols so they don't collide with
+// non-exported symbols from other modules?
+
+// FIXME: Formally-internal-linkage symbols that are used from an exported
+// symbol need a mangled name and external linkage.
+
+// FIXME: const-qualified variables don't have implicit internal linkage when owned by a module.
diff --git a/test/CodeGenCXX/ms-inline-asm-return.cpp b/test/CodeGenCXX/ms-inline-asm-return.cpp
index 1219c617ddc7..51671c0bcdaa 100644
--- a/test/CodeGenCXX/ms-inline-asm-return.cpp
+++ b/test/CodeGenCXX/ms-inline-asm-return.cpp
@@ -50,8 +50,8 @@ char f_i8() {
bool f_i1() {
__asm {
- mov eax, 1
- mov edx, 1
+ mov eax, 1L
+ mov edx, 1U
}
}
// CHECK-LABEL: define zeroext i1 @f_i1()
@@ -80,12 +80,12 @@ struct EightChars {
};
EightChars f_s8() {
__asm {
- mov eax, 0x01010101
- mov edx, 0x01010101
+ mov eax, 01010101h
+ mov edx, 01010101b
}
}
// CHECK-LABEL: define i64 @f_s8()
-// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$0x01010101\0A\09mov edx, $$0x01010101", "=A,~{eax},{{.*}}"
+// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$01010101h\0A\09mov edx, $$01010101b", "=A,~{eax},{{.*}}"
// CHECK: store i64 %[[r]], i64* %{{.*}}
// CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}}
// CHECK: ret i64 %[[r_i64]]
diff --git a/test/CodeGenCXX/ms-thread_local.cpp b/test/CodeGenCXX/ms-thread_local.cpp
index c29473fd6fca..5183ab5c32e1 100644
--- a/test/CodeGenCXX/ms-thread_local.cpp
+++ b/test/CodeGenCXX/ms-thread_local.cpp
@@ -26,3 +26,8 @@ A f() {
(void)b;
return c;
}
+
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]}
+// CHECK: ![[link_opts]] = !{![[dyn_tls_init:[0-9]+]]}
+// CHECK: ![[dyn_tls_init]] = !{!"/include:___dyn_tls_init@12"}
diff --git a/test/CodeGenCXX/naked.cpp b/test/CodeGenCXX/naked.cpp
new file mode 100644
index 000000000000..34f22b3636b5
--- /dev/null
+++ b/test/CodeGenCXX/naked.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows -emit-llvm %s -o - | FileCheck %s
+
+class TestNaked {
+public:
+ void NakedFunction();
+};
+
+__attribute__((naked)) void TestNaked::NakedFunction() {
+ // CHECK-LABEL: define {{(x86_thiscallcc )?}}void @
+ // CHECK: call void asm sideeffect
+ asm("");
+}
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 602f93c34f01..0429ae770bc8 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// CHECK: @[[ABC4:.*]] = {{.*}} constant [4 x i8] c"abc\00"
+// CHECK: @[[ABC15:.*]] = {{.*}} constant [15 x i8] c"abc\00\00\00\00
+
// CHECK-LABEL: define void @_Z2fni
void fn(int n) {
// CHECK: icmp ult i{{32|64}} %{{[^ ]+}}, 3
@@ -11,13 +14,6 @@ void fn(int n) {
new int[n] { 1, 2, 3 };
}
-// CHECK-LABEL: define void @_Z15const_underflowv
-void const_underflow() {
- // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
- // CHECK: call i8* @_Zna{{.}}(i{{32|64}} -1)
- new int[2] { 1, 2, 3 };
-}
-
// CHECK-LABEL: define void @_Z11const_exactv
void const_exact() {
// CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
@@ -46,3 +42,77 @@ void check_array_value_init() {
// CHECK: icmp eq
// CHECK: br i1
}
+
+// CHECK-LABEL: define void @_Z15string_nonconsti
+void string_nonconst(int n) {
+ // CHECK: icmp slt i{{32|64}} %{{[^ ]+}}, 4
+ // FIXME: Conditionally throw an exception rather than passing -1 to alloc function
+ // CHECK: select
+ // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}}
+ // CHECK: call void @llvm.memcpy{{.*}}(i8* %[[PTR]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4,
+ // CHECK: %[[REST:.*]] = getelementptr inbounds i8, i8* %[[PTR]], i32 4
+ // CHECK: %[[RESTSIZE:.*]] = sub {{.*}}, 4
+ // CHECK: call void @llvm.memset{{.*}}(i8* %[[REST]], i8 0, i{{32|64}} %[[RESTSIZE]],
+ new char[n] { "abc" };
+}
+
+// CHECK-LABEL: define void @_Z12string_exactv
+void string_exact() {
+ // CHECK-NOT: icmp
+ // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 4)
+ // CHECK: call void @llvm.memcpy{{.*}}(i8* %[[PTR]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4,
+ // CHECK-NOT: memset
+ new char[4] { "abc" };
+}
+
+// CHECK-LABEL: define void @_Z17string_sufficientv
+void string_sufficient() {
+ // CHECK-NOT: icmp
+ // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 15)
+ // FIXME: For very large arrays, it would be preferable to emit a small copy and a memset.
+ // CHECK: call void @llvm.memcpy{{.*}}(i8* %[[PTR]], i8* getelementptr inbounds ([15 x i8], [15 x i8]* @[[ABC15]], i32 0, i32 0), i32 15,
+ // CHECK-NOT: memset
+ new char[15] { "abc" };
+}
+
+// CHECK-LABEL: define void @_Z10aggr_exactv
+void aggr_exact() {
+ // CHECK-NOT: icmp
+ // CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 16)
+ // CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]*
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}}
+ // CHECK: store i32 1, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 1{{$}}
+ // CHECK: store i32 2, i32* %[[FIELD]]
+ // CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 1{{$}}
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 0{{$}}
+ // CHECK: store i32 3, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 1{{$}}
+ // CHECK: store i32 0, i32* %[[FIELD]]
+ // CHECK-NOT: store
+ // CHECK-NOT: memset
+ struct Aggr { int a, b; };
+ new Aggr[2] { 1, 2, 3 };
+}
+
+// CHECK-LABEL: define void @_Z15aggr_sufficienti
+void aggr_sufficient(int n) {
+ // CHECK: icmp ult i32 %{{.*}}, 2
+ // CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(
+ // CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]*
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}}
+ // CHECK: store i32 1, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 1{{$}}
+ // CHECK: store i32 2, i32* %[[FIELD]]
+ // CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 1{{$}}
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 0{{$}}
+ // CHECK: store i32 3, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 1{{$}}
+ // CHECK: store i32 0, i32* %[[FIELD]]
+ // CHECK: %[[PTR2:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 1{{$}}
+ // CHECK: %[[REMAIN:.*]] = sub i32 {{.*}}, 16
+ // CHECK: %[[MEM:.*]] = bitcast %[[AGGR]]* %[[PTR2]] to i8*
+ // CHECK: call void @llvm.memset{{.*}}(i8* %[[MEM]], i8 0, i32 %[[REMAIN]],
+ struct Aggr { int a, b; };
+ new Aggr[n] { 1, 2, 3 };
+}
diff --git a/test/CodeGenCXX/no-exceptions.cpp b/test/CodeGenCXX/no-exceptions.cpp
index ceb3b8e80396..b970ef2c5a27 100644
--- a/test/CodeGenCXX/no-exceptions.cpp
+++ b/test/CodeGenCXX/no-exceptions.cpp
@@ -11,4 +11,4 @@ void f() throw (int) {
// CHECK: ret void
}
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index 8744d141dddc..d02206abae50 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s
// Test code generation for the named return value optimization.
class X {
@@ -91,16 +92,18 @@ X test2(bool B) {
// -> %eh.cleanup
// %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
- // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
+ // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
// -> %eh.cleanup, %terminate.lpad
+ // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
// %if.end: returning 'y'
// CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
// -> %cleanup, %lpad1
// %cleanup: normal cleanup for 'y'
- // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
+ // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
// -> %invoke.cont11, %lpad
+ // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
// %invoke.cont11: normal cleanup for 'x'
// CHECK-EH: call void @llvm.lifetime.end
@@ -109,19 +112,20 @@ X test2(bool B) {
// CHECK-EH-NEXT: ret void
// %eh.cleanup: EH cleanup for 'x'
- // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
+ // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
// -> %invoke.cont17, %terminate.lpad
+ // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
// %invoke.cont17: rethrow block for %eh.cleanup.
// This really should be elsewhere in the function.
// CHECK-EH: resume { i8*, i32 }
// %terminate.lpad: terminate landing pad.
- // CHECK-EH: [[T0:%.*]] = landingpad { i8*, i32 }
- // CHECK-EH-NEXT: catch i8* null
- // CHECK-EH-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
- // CHECK-EH-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
- // CHECK-EH-NEXT: unreachable
+ // CHECK-EH-03: [[T0:%.*]] = landingpad { i8*, i32 }
+ // CHECK-EH-03-NEXT: catch i8* null
+ // CHECK-EH-03-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
+ // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
+ // CHECK-EH-03-NEXT: unreachable
}
@@ -178,11 +182,11 @@ X test6() {
return a;
// CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
// CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0
- // CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* [[PTR]])
+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* nonnull [[PTR]])
// CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* nonnull [[A]])
// CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull dereferenceable({{[0-9]+}}) [[A]])
// CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* nonnull [[A]])
- // CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* [[PTR]])
+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* nonnull [[PTR]])
// CHECK-NEXT: ret void
}
@@ -217,4 +221,4 @@ Y<int> test9() {
// CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
// CHECK: tail call {{.*}} @_ZN1YIiEC1Ev
-// CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind }
+// CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/test/CodeGenCXX/optnone-class-members.cpp b/test/CodeGenCXX/optnone-class-members.cpp
index 751f3dd2bf08..70e3ee76e60a 100644
--- a/test/CodeGenCXX/optnone-class-members.cpp
+++ b/test/CodeGenCXX/optnone-class-members.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -x c++ | FileCheck %s
+// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-optzns -emit-llvm -x c++ | FileCheck %s
// Test attribute 'optnone' on methods:
// -- member functions;
diff --git a/test/CodeGenCXX/optnone-def-decl.cpp b/test/CodeGenCXX/optnone-def-decl.cpp
index 0240189c5089..4008bbe685f3 100644
--- a/test/CodeGenCXX/optnone-def-decl.cpp
+++ b/test/CodeGenCXX/optnone-def-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-optzns -emit-llvm -o - | FileCheck %s
// Test optnone on both function declarations and function definitions.
// Verify also that we don't generate invalid IR functions with
diff --git a/test/CodeGenCXX/partial-destruction.cpp b/test/CodeGenCXX/partial-destruction.cpp
index 4097fbfaa19c..a5a2f40eb071 100644
--- a/test/CodeGenCXX/partial-destruction.cpp
+++ b/test/CodeGenCXX/partial-destruction.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++03 | FileCheck %s -check-prefixes=CHECK,CHECKv03
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++11 | FileCheck %s -check-prefixes=CHECK,CHECKv11
// Test IR generation for partial destruction of aggregates.
@@ -45,7 +46,8 @@ namespace test0 {
// CHECK-NEXT: br label
// CHECK: [[ED_AFTER:%.*]] = phi [[A]]* [ [[ED_END]], {{%.*}} ], [ [[ED_CUR:%.*]], {{%.*}} ]
// CHECK-NEXT: [[ED_CUR]] = getelementptr inbounds [[A]], [[A]]* [[ED_AFTER]], i64 -1
- // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+ // CHECKv11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
// CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_CUR]], [[ED_BEGIN]]
// CHECK-NEXT: br i1 [[T0]],
// CHECK: ret void
@@ -58,7 +60,8 @@ namespace test0 {
// CHECK-NEXT: br i1 [[T0]],
// CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[PARTIAL_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
// CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1
- // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECKv11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
// CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E_BEGIN]]
// CHECK-NEXT: br i1 [[T0]],
@@ -73,20 +76,21 @@ namespace test0 {
// FIXME: There's some really bad block ordering here which causes
// the partial destroy for the primary normal destructor to fall
// within the primary EH destructor.
- // CHECK: landingpad { i8*, i32 }
- // CHECK-NEXT: cleanup
- // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
- // CHECK-NEXT: br i1 [[T0]]
- // CHECK: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
- // CHECK-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]], [[A]]* [[EDD_AFTER]], i64 -1
- // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]])
- // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]]
- // CHECK-NEXT: br i1 [[T0]]
+ // CHECKv03: landingpad { i8*, i32 }
+ // CHECKv03-NEXT: cleanup
+ // CHECKv03: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
+ // CHECKv03-NEXT: br i1 [[T0]]
+ // CHECKv03: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
+ // CHECKv03-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]], [[A]]* [[EDD_AFTER]], i64 -1
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]])
+ // CHECKv03: [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]]
+ // CHECKv03-NEXT: br i1 [[T0]]
// Back to the primary EH destructor.
// CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[E_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
// CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1
- // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECKv11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
// CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E0]]
// CHECK-NEXT: br i1 [[T0]],
@@ -120,8 +124,10 @@ namespace test1 {
// CHECK-NEXT: cleanup
// CHECK: landingpad { i8*, i32 }
// CHECK-NEXT: cleanup
- // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
- // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
+ // CHECKv03: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
+ // CHECKv03: invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
+ // CHECKv11: call void @_ZN5test11AD1Ev([[A]]* [[Y]])
+ // CHECKv11: call void @_ZN5test11AD1Ev([[A]]* [[X]])
}
namespace test2 {
@@ -153,7 +159,8 @@ namespace test2 {
// CHECK-NEXT: br i1 [[EMPTY]],
// CHECK: [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ]
// CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1
- // CHECK-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+ // CHECKv03-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+ // CHECKv11-NEXT: call void @_ZN5test21AD1Ev([[A]]* [[DEL]])
// CHECK: [[T0:%.*]] = icmp eq [[A]]* [[DEL]], [[BEGIN]]
// CHECK-NEXT: br i1 [[T0]],
}
diff --git a/test/CodeGenCXX/pr24097.cpp b/test/CodeGenCXX/pr24097.cpp
index 122bf88506d3..cdf78d20cbda 100644
--- a/test/CodeGenCXX/pr24097.cpp
+++ b/test/CodeGenCXX/pr24097.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -fvisibility hidden -emit-llvm -O1 -disable-llvm-optzns -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -fvisibility hidden -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s
struct Filter {
virtual void Foo();
diff --git a/test/CodeGenCXX/pr30731.cpp b/test/CodeGenCXX/pr30731.cpp
new file mode 100644
index 000000000000..078f21ceda4f
--- /dev/null
+++ b/test/CodeGenCXX/pr30731.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm -flto -std=c++11 -o - %s | FileCheck %s
+
+struct A {
+ virtual ~A();
+};
+
+struct B {};
+
+struct C {
+ virtual void f();
+};
+
+struct S : A, virtual B, C {
+ void f() override;
+};
+
+void f(S* s) { s->f(); }
+
+// CHECK-LABEL: define void @"\01?f@@YAXPAUS@@@Z"
+// CHECK: call
+// CHECK: ret void
diff --git a/test/CodeGenCXX/pragma-loop-distribute.cpp b/test/CodeGenCXX/pragma-loop-distribute.cpp
new file mode 100644
index 000000000000..a6925593b818
--- /dev/null
+++ b/test/CodeGenCXX/pragma-loop-distribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void while_test(int *List, int Length, int *List2, int Length2) {
+ // CHECK: define {{.*}} @_Z10while_test
+ int i = 0;
+
+#pragma clang loop distribute(enable)
+ while (i < Length) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = i * 2;
+ i++;
+ }
+
+ i = 0;
+ while (i < Length2) {
+ // CHECK-NOT: br label {{.*}}, !llvm.loop
+ List2[i] = i * 2;
+ i++;
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[DISTRIBUTE_ENABLE:.*]]}
+// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
diff --git a/test/CodeGenCXX/pragma-loop-safety.cpp b/test/CodeGenCXX/pragma-loop-safety.cpp
index 393f0a3e43fe..c6ce82737d0b 100644
--- a/test/CodeGenCXX/pragma-loop-safety.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -10,12 +10,12 @@ void vectorize_test(int *List, int Length) {
#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
for (int i = 0; i < Length; i++) {
// CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
- // CHECK-NEXT: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
- // CHECK-NEXT: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
- // CHECK-NEXT: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
- // CHECK-NEXT: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
- // CHECK-NEXT: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
- // CHECK-NEXT: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK-DAG: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
+ // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK-DAG: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
+ // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+ // CHECK-DAG: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
+ // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
// CHECK-NEXT: br label [[LOOP1_INC:[^,]+]]
List[i] = i * 2;
@@ -33,12 +33,12 @@ void interleave_test(int *List, int Length) {
#pragma clang loop interleave(assume_safety) vectorize(disable) unroll(disable)
for (int i = 0; i < Length; i++) {
// CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
- // CHECK-NEXT: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
- // CHECK-NEXT: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
- // CHECK-NEXT: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
- // CHECK-NEXT: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
- // CHECK-NEXT: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
- // CHECK-NEXT: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK-DAG: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
+ // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK-DAG: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
+ // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+ // CHECK-DAG: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
+ // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
// CHECK-NEXT: br label [[LOOP2_INC:[^,]+]]
List[i] = i * 2;
diff --git a/test/CodeGenCXX/predefined-expr-cxx14.cpp b/test/CodeGenCXX/predefined-expr-cxx14.cpp
index 1f035757dea9..dd531e3112b6 100644
--- a/test/CodeGenCXX/predefined-expr-cxx14.cpp
+++ b/test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -17,8 +17,8 @@
// CHECK-DAG: @__func__._ZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEv = private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00"
// CHECK-DAG: @__PRETTY_FUNCTION__._ZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEv = private unnamed_addr constant [60 x i8] c"auto *ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
-// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrD2Ev_block_invoke\00"
-// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrC2Ev_block_invoke\00"
+// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [31 x i8] c"~ClassBlockConstr_block_invoke\00"
+// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [30 x i8] c"ClassBlockConstr_block_invoke\00"
int printf(const char * _Format, ...);
diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp
index 02498a36a180..54faa6488116 100644
--- a/test/CodeGenCXX/reference-cast.cpp
+++ b/test/CodeGenCXX/reference-cast.cpp
@@ -193,4 +193,4 @@ namespace PR10650 {
// CHECK: store i64
}
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/regcall.cpp b/test/CodeGenCXX/regcall.cpp
new file mode 100644
index 000000000000..0cc6ad009324
--- /dev/null
+++ b/test/CodeGenCXX/regcall.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN64 %s
+// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -check-prefix=CHECK-WIN64 %s
+// RUN: %clang_cc1 -triple i386-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -check-prefix=CHECK-WIN32 %s
+
+int __regcall foo(int i);
+
+int main()
+{
+ int p = 0, _data;
+ auto lambda = [&](int parameter) -> int {
+ _data = foo(parameter);
+ return _data;
+ };
+ return lambda(p);
+}
+// CHECK-LIN: call x86_regcallcc {{.+}} @_Z15__regcall3__foo
+// CHECK-WIN64: call x86_regcallcc {{.+}} @"\01?foo@@YwHH@Z"
+// CHECK-WIN32: call x86_regcallcc {{.+}} @"\01?foo@@YwHH@Z"
+
+int __regcall foo (int i){
+ return i;
+}
+// CHECK-LIN: define x86_regcallcc {{.+}}@_Z15__regcall3__foo
+// CHECK-WIN64: define x86_regcallcc {{.+}}@"\01?foo@@YwHH@Z"
+// CHECK-WIN32: define x86_regcallcc {{.+}}@"\01?foo@@YwHH@Z"
+
+// used to give a body to test_class functions
+static int x = 0;
+class test_class {
+ int a;
+public:
+#ifndef WIN_TEST
+ __regcall
+#endif
+ test_class(){++x;}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC1Ev
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC2Ev
+ // Windows ignores calling convention on constructor/destructors.
+ // CHECK-WIN64-DAG: define linkonce_odr %class.test_class* @"\01??0test_class@@QEAA@XZ"
+ // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc %class.test_class* @"\01??0test_class@@QAE@XZ"
+
+#ifndef WIN_TEST
+ __regcall
+#endif
+ ~test_class(){--x;}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev
+ // Windows ignores calling convention on constructor/destructors.
+ // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAA@XZ"
+ // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAE@XZ"
+
+ test_class& __regcall operator+=(const test_class&){
+ return *this;
+ }
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @_ZN10test_classpLERKS_
+ // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @"\01??Ytest_class@@QEAwAEAV0@AEBV0@@Z"
+ // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @"\01??Ytest_class@@QAwAAV0@ABV0@@Z"
+ void __regcall do_thing(){}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__do_thingEv
+ // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01?do_thing@test_class@@QEAwXXZ"
+ // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01?do_thing@test_class@@QAwXXZ"
+
+ template<typename T>
+ void __regcall tempFunc(T i){}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__tempFuncIiEEvT_
+ // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
+ // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
+};
+
+bool __regcall operator ==(const test_class&, const test_class&){ --x; return false;}
+// CHECK-LIN-DAG: define x86_regcallcc zeroext i1 @_ZeqRK10test_classS1_
+// CHECK-WIN64-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NAEBVtest_class@@0@Z"
+// CHECK-WIN32-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NABVtest_class@@0@Z"
+
+test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
+// CHECK-LIN64-DAG: define x86_regcallcc %class.test_class @_Zli11_test_classy(i64)
+// CHECK-LIN32-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret %agg.result, i64)
+// CHECK-WIN64-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
+// CHECK-WIN32-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
+
+template<typename T>
+void __regcall freeTempFunc(T i){}
+// CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_Z24__regcall3__freeTempFuncIiEvT_
+// CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
+// CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
+
+// class to force generation of functions
+void force_gen() {
+ test_class t;
+ test_class t2 = 12_test_class;
+ t += t2;
+ auto t3 = 100_test_class;
+ t3.tempFunc(1);
+ freeTempFunc(1);
+ t3.do_thing();
+}
diff --git a/test/CodeGenCXX/rtti-mingw64.cpp b/test/CodeGenCXX/rtti-mingw64.cpp
new file mode 100644
index 000000000000..818b11b64bc5
--- /dev/null
+++ b/test/CodeGenCXX/rtti-mingw64.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu %s -emit-llvm -o - | FileCheck %s
+struct A { int a; };
+struct B : virtual A { int b; };
+B b;
+
+// CHECK: @_ZTI1B = linkonce_odr constant { i8*, i8*, i32, i32, i8*, i64 }
+// CHECK-SAME: i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*),
+// CHECK-SAME: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0),
+// CHECK-SAME: i32 0,
+// CHECK-SAME: i32 1,
+// CHECK-SAME: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*),
+// This i64 is important, it should be an i64, not an i32.
+// CHECK-SAME: i64 -6141 }, comdat
diff --git a/test/CodeGenCXX/rtti-qualfn.cpp b/test/CodeGenCXX/rtti-qualfn.cpp
new file mode 100644
index 000000000000..329cd50547ab
--- /dev/null
+++ b/test/CodeGenCXX/rtti-qualfn.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++1z -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions | FileCheck %s
+
+#include "typeinfo"
+
+struct A {};
+
+// CHECK-DAG: @_ZTIFvvE = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__function_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @_ZTSFvvE, i32 0, i32 0) }, comdat
+// CHECK-DAG: @_ZTIPDoFvvE = linkonce_odr constant { i8*, i8*, i32, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv119__pointer_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_ZTSPDoFvvE, i32 0, i32 0), i32 64, i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*) }, comdat
+auto &ti_noexcept_ptr = typeid(void (A::*)() noexcept);
+// CHECK-DAG: @_ZTIM1ADoFvvE = linkonce_odr constant { i8*, i8*, i32, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @_ZTSM1ADoFvvE, i32 0, i32 0), i32 64, i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }, comdat
+auto &ti_noexcept_memptr = typeid(void (A::*)() noexcept);
+
+// CHECK-LABEL: define void @_Z1fv(
+__attribute__((noreturn)) void f() noexcept {
+ // CHECK: call void @__cxa_throw({{.*}}@_ZTIPDoFvvE
+ throw f;
+}
+
+// CHECK-LABEL: define void @_Z1gM1ADoFvvE(
+void g(__attribute__((noreturn)) void (A::*p)() noexcept) {
+ // CHECK: call void @__cxa_throw({{.*}}@_ZTIM1ADoFvvE
+ throw p;
+}
diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp
new file mode 100644
index 000000000000..76c002c0e407
--- /dev/null
+++ b/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -0,0 +1,158 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-MS -check-prefix CHECK-MS-DYNAMIC
+// RUN: %clang_cc1 -triple i686-windows-msvc -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-MS -check-prefix CHECK-MS-STATIC
+
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-NODECL-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-NODECL-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DIMPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IMPORT-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DIMPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IMPORT-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DEXPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DEXPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DDECL -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-DECL-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DDECL -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-DECL-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IA-ATEXIT
+// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IA-ATEXIT
+
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+
+#if defined(IMPORT_DECLARATIONS)
+namespace __cxxabiv1 {
+extern "C" {
+__declspec(dllimport) void __cxa_guard_acquire(unsigned long long *);
+__declspec(dllimport) unsigned char *__cxa_allocate_exception(unsigned long);
+}
+extern "C" __declspec(dllimport) void __cxa_guard_release(unsigned long long *);
+}
+namespace std {
+__declspec(dllimport) __declspec(noreturn) void terminate();
+}
+#elif defined(EXPORT_DECLARATIONS)
+namespace __cxxabiv1 {
+extern "C" {
+__declspec(dllexport) void __cxa_guard_acquire(unsigned long long *);
+__declspec(dllexport) unsigned char *__cxa_allocate_exception(unsigned long);
+}
+extern "C" void __declspec(dllexport) __cxa_guard_release(unsigned long long *);
+}
+namespace std {
+__declspec(dllexport) __declspec(noreturn) void terminate();
+}
+#elif defined(DECL)
+namespace __cxxabiv1 {
+extern "C" unsigned char *__cxa_allocate_exception(unsigned long);
+}
+namespace std {
+__declspec(noreturn) void terminate();
+}
+#else
+namespace std {
+__declspec(noreturn) void terminate();
+}
+#endif
+
+struct s {
+ s() = default;
+ s(unsigned char) { throw 0; }
+ int m() const;
+};
+
+struct t {
+ ~t();
+ int m() const;
+};
+
+struct u {
+ ~u();
+};
+
+s o;
+thread_local t t;
+u v;
+__declspec(thread) s q;
+
+void __declspec(noinline) f() {
+ throw 0;
+}
+
+void g();
+void __declspec(noinline) h() {
+ try {
+ g();
+ } catch (const int &) {
+ return;
+ } catch (...) {
+ throw;
+ }
+}
+
+void i() {
+ s r(static_cast<unsigned char>('\t'));
+}
+
+int j() {
+ static thread_local struct t v;
+ static struct t *w = new struct t;
+ return w->m() ? v.m() : w->m();
+}
+
+void k() noexcept {
+ g();
+}
+
+void l() {
+ std::terminate();
+}
+
+// CHECK-MS-DAG: @_Init_thread_epoch = external thread_local global i32
+// CHECK-MS-DAG: declare i32 @__tlregdtor(void ()*)
+// CHECK-MS-DAG: declare i32 @atexit(void ()*)
+// CHECK-MS-DYNAMIC-DAG: declare dllimport {{.*}} void @_CxxThrowException
+// CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException
+// CHECK-MS-DAG: declare noalias i8* @"\01??2@YAPAXI@Z"
+// CHECK-MS-DAG: declare void @_Init_thread_header(i32*)
+// CHECK-MS-DAG: declare void @_Init_thread_footer(i32*)
+
+// CHECK-IA-DAG: declare i32 @__gxx_personality_v0(...)
+// CHECK-IA-DAG: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+
+// CHECK-DYNAMIC-IA-DAG: declare dllimport i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// CHECK-DYNAMIC-IA-DAG: declare dllimport i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+// CHECK-DYNAMIC-IA-DECL-DAG: declare i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-NODECL-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-IMPORT-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-EXPORT-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-DAG: declare dllimport void @__cxa_throw(i8*, i8*, i8*)
+// CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllexport i32 @__cxa_guard_acquire(i64*)
+// CHECK-IA-DAG: declare noalias i8* @_Znwj(i32)
+// CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYANMIC-IA-DAG: declare dllimport void @_ZSt9terminatev()
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @_ZSt9terminatev()
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllexport void @_ZSt9terminatev()
+
+// CHECK-STATIC-IA-DAG: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// CHECK-STATIC-IA-DAG: declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+// CHECK-STATIC-IA-DAG: declare i8* @__cxa_allocate_exception(i32)
+// CHECK-STATIC-IA-DAG: declare void @__cxa_throw(i8*, i8*, i8*)
+// CHECK-STATIC-DECL-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-NODECL-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-IMPORT-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-EXPORT-IA-DAG: declare i32 @__cxa_guard_acquire(i64*)
+// CHECK-IA-DAG: declare noalias i8* @_Znwj(i32)
+// CHECK-STATIC-DECL-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-NODECL-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-IMPORT-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-EXPORT-IA-DAG: declare void @__cxa_guard_release(i64*)
+// CHECK-STATIC-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-STATIC-NODECL-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-STATIC-IMPORT-IA-DAG: declare void @_ZSt9terminatev()
+// CHECK-STATIC-EXPORT-IA-DAG: declare dllexport void @_ZSt9terminatev()
+
diff --git a/test/CodeGenCXX/sanitize-dtor-bit-field.cpp b/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
index d4497f6aac0b..19c46ba64a98 100644
--- a/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -1,6 +1,6 @@
// Test -fsanitize-memory-use-after-dtor
-// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
// 24 bytes total
struct Packed {
diff --git a/test/CodeGenCXX/sanitize-dtor-derived-class.cpp b/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
index f3134711824d..618096aeebd7 100644
--- a/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
// Base dtor poisons members
// Complete dtor poisons vtable ptr after destroying members and
diff --git a/test/CodeGenCXX/sanitize-dtor-tail-call.cpp b/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
index de2fd8c75c88..d6f5719c8bf3 100644
--- a/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
@@ -1,6 +1,6 @@
// Test -fsanitize-memory-use-after-dtor
-// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
struct Simple {
int x_;
diff --git a/test/CodeGenCXX/sanitize-dtor-trivial.cpp b/test/CodeGenCXX/sanitize-dtor-trivial.cpp
index 39f580af97e7..9e328c0a2895 100644
--- a/test/CodeGenCXX/sanitize-dtor-trivial.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-trivial.cpp
@@ -1,6 +1,6 @@
// Test -fsanitize-memory-use-after-dtor
-// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
// TODO Success pending on resolution of issue:
// https://github.com/google/sanitizers/issues/596
diff --git a/test/CodeGenCXX/sanitize-dtor-vtable.cpp b/test/CodeGenCXX/sanitize-dtor-vtable.cpp
index 78be7949c32c..2318ef0d8003 100644
--- a/test/CodeGenCXX/sanitize-dtor-vtable.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
class A {
public:
diff --git a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
index 4734c02bc52e..83a2d617e878 100644
--- a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
@@ -11,7 +11,7 @@ struct A {
};
// CHECK-LABEL: define void @_ZN5Test11AD2Ev
-// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
+// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
A::~A()
{
}
@@ -27,7 +27,7 @@ struct A {
};
// CHECK-LABEL: define void @_ZN5Test21AD2Ev
-// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test21AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test21AE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test31AE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test41AE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test51AE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test61AE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test71AE, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**), i32 (...)***
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test81AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
A::~A()
{
}
diff --git a/test/CodeGenCXX/stack-reuse-miscompile.cpp b/test/CodeGenCXX/stack-reuse-miscompile.cpp
index 63d15fd1e8c9..3b860a573955 100644
--- a/test/CodeGenCXX/stack-reuse-miscompile.cpp
+++ b/test/CodeGenCXX/stack-reuse-miscompile.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -S -target armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -mllvm -disable-llvm-optzns -S %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -disable-llvm-passes -std=c++03 %s -o - | FileCheck %s
// This test should not to generate llvm.lifetime.start/llvm.lifetime.end for
// f function because all temporary objects in this function are used for the
diff --git a/test/CodeGenCXX/stack-reuse.cpp b/test/CodeGenCXX/stack-reuse.cpp
index d6340ef2c10b..8325604391ae 100644
--- a/test/CodeGenCXX/stack-reuse.cpp
+++ b/test/CodeGenCXX/stack-reuse.cpp
@@ -132,8 +132,8 @@ void large_auto_object() {
int large_combiner_test(S_large s) {
// CHECK-LABEL: define i32 @large_combiner_test
-// CHECK: [[T1:%.*]] = alloca %struct.Combiner
// CHECK: [[T2:%.*]] = alloca %struct.Combiner
+// CHECK: [[T1:%.*]] = alloca %struct.Combiner
// CHECK: [[T3:%.*]] = call %struct.Combiner* @_ZN8CombinerC1E7S_large(%struct.Combiner* nonnull [[T1]], [9 x i32] %s.coerce)
// CHECK: call void @_ZN8Combiner1fEv(%struct.Combiner* nonnull sret [[T2]], %struct.Combiner* nonnull [[T1]])
// CHECK: [[T4:%.*]] = getelementptr inbounds %struct.Combiner, %struct.Combiner* [[T2]], i32 0, i32 0, i32 0, i32 0
diff --git a/test/CodeGenCXX/strict-vtable-pointers.cpp b/test/CodeGenCXX/strict-vtable-pointers.cpp
index 33f63994d7c0..21f85b1c5772 100644
--- a/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ b/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -disable-llvm-optzns -O2 -emit-llvm -o %t.ll
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -disable-llvm-passes -O2 -emit-llvm -o %t.ll
// RUN: FileCheck --check-prefix=CHECK-CTORS %s < %t.ll
// RUN: FileCheck --check-prefix=CHECK-NEW %s < %t.ll
// RUN: FileCheck --check-prefix=CHECK-DTORS %s < %t.ll
@@ -54,7 +54,7 @@ struct DynamicFrom2Virtuals :
// CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
// CHECK-NEW-NOT: @llvm.invariant.group.barrier(
-// CHECK-NEW-LABEL: }
+// CHECK-NEW-LABEL: {{^}}}
void LocalObjects() {
DynamicBase1 DB;
DB.foo();
@@ -82,12 +82,12 @@ void LocalObjects() {
struct DynamicFromVirtualStatic1;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
// CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
struct DynamicFrom2Virtuals;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
// CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
// CHECK-NEW-LABEL: define void @_Z9Pointers1v()
@@ -97,7 +97,7 @@ struct DynamicFrom2Virtuals;
// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS2:.*]])
// CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
-// CHECK-NEW-LABEL: }
+// CHECK-NEW-LABEL: {{^}}}
void Pointers1() {
DynamicBase1 *DB = new DynamicBase1;
DB->foo();
@@ -113,7 +113,7 @@ void Pointers1() {
// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(
// CHECK-NEW: call i8* @llvm.invariant.group.barrier(
// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
-// CHECK-NEW-LABEL: }
+// CHECK-NEW-LABEL: {{^}}}
void HackingObjects() {
DynamicBase1 DB;
DB.foo();
@@ -132,7 +132,7 @@ void HackingObjects() {
struct DynamicBase1;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
// CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
struct DynamicDerived;
@@ -147,7 +147,7 @@ struct DynamicDerived;
// CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)***
// CHECK-CTORS: store {{.*}} %[[THIS5]]
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
struct DynamicDerivedMultiple;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev(
@@ -166,49 +166,49 @@ struct DynamicDerivedMultiple;
// CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
-// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 2) {{.*}} %[[THIS10]]
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange 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, i32 0, i32 6) {{.*}} %[[THIS12]]
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]]
+// CHECK-CTORS-LABEL: {{^}}}
struct DynamicFromStatic;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
// CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
-// CHECK-CTORS-LABEL: }
+// CHECK-CTORS-LABEL: {{^}}}
/** DTORS **/
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic2D2Ev(
// CHECK-DTORS-NOT: invariant.barrier
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
// CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
// CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
-// CHECK-DTORS-LABEL: }
+// CHECK-DTORS-LABEL: {{^}}}
// CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:.*]], ![[SEC:.*]]{{.*}}}
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index 90b8099f0a26..3d0ce234371f 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
// CHECK: @_ZN7PR100011xE = global
// CHECK-NOT: @_ZN7PR100014kBarE = external global i32
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index c537124c468c..bad51ba353cd 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -779,6 +779,36 @@ namespace MultipleExtension {
}
}
+namespace ArrayAccess {
+ struct A { A(int); ~A(); };
+ void g();
+ void f() {
+ using T = A[3];
+
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ A &&a = T{1, 2, 3}[1];
+
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ A &&b = 2[T{4, 5, 6}];
+
+ // CHECK: call void @_ZN11ArrayAccess1gEv(
+ g();
+
+ // CHECK: call void @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AD
+ }
+}
+
namespace PR14130 {
struct S { S(int); };
struct U { S &&s; };
diff --git a/test/CodeGenCXX/threadsafe-statics.cpp b/test/CodeGenCXX/threadsafe-statics.cpp
index 9aecc2d0db68..7cb7003fc0ca 100644
--- a/test/CodeGenCXX/threadsafe-statics.cpp
+++ b/test/CodeGenCXX/threadsafe-statics.cpp
@@ -22,6 +22,6 @@ void g() {
// NO-TSS-NOT: call void @__cxa_guard_release
// NO-TSS: ret void
-// WITH-TSS: attributes [[NUW]] = { nounwind{{.*}} }
+// WITH-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} }
-// NO-TSS: attributes [[NUW]] = { nounwind{{.*}} }
+// NO-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index 3a598b90afe1..26e166c7bf4c 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -1,9 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o %t
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o %t.opt -O1 -disable-llvm-optzns
-// RUN: FileCheck %s < %t
-// RUN: FileCheck %s < %t.opt
-// RUN: FileCheck --check-prefix=CHECK-NONOPT %s < %t
-// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-NONOPT %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck --check-prefix=CHECK --check-prefix=CHECK-OPT %s
namespace Test1 {
@@ -405,4 +401,5 @@ D::~D() {}
// CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
// CHECK-OPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
-// CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} }
+// CHECK-NONOPT: attributes [[NUW]] = { noinline nounwind uwtable{{.*}} }
+// CHECK-OPT: attributes [[NUW]] = { nounwind uwtable{{.*}} }
diff --git a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
new file mode 100644
index 000000000000..bc8861aa8314
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s
+
+struct Base1 {
+ virtual void f1() {}
+};
+
+struct Base2 {
+ virtual void f1() {}
+};
+
+struct Derived1 final : Base1 {
+ void f1() override {}
+};
+
+struct Derived2 final : Base1, Base2 {
+ void f1() override {}
+};
+
+struct Derived3 : Base1 {
+ void f1() override /* nofinal */ {}
+};
+
+struct Derived4 final : Base1 {
+ void f1() override final {}
+};
+
+// CHECK: [[UBSAN_TI_DERIVED1_1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived1 to i8*
+// CHECK: [[UBSAN_TI_DERIVED2_1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived2 to i8*
+// CHECK: [[UBSAN_TI_DERIVED2_2:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived2 to i8*
+// CHECK: [[UBSAN_TI_DERIVED3:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived3 to i8*
+// CHECK: [[UBSAN_TI_BASE1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI5Base1 to i8*
+// CHECK: [[UBSAN_TI_DERIVED4_1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived4 to i8*
+// CHECK: [[UBSAN_TI_DERIVED4_2:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived4 to i8*
+
+// CHECK-LABEL: define void @_Z2t1v
+void t1() {
+ Derived1 d1;
+ static_cast<Base1 *>(&d1)->f1(); //< Devirt Base1::f1 to Derived1::f1.
+ // CHECK: %[[D1:[0-9]+]] = ptrtoint %struct.Derived1* %d1 to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED1_1]] {{.*}}, i{{[0-9]+}} %[[D1]]
+}
+
+// CHECK-LABEL: define void @_Z2t2v
+void t2() {
+ Derived2 d2;
+ static_cast<Base1 *>(&d2)->f1(); //< Devirt Base1::f1 to Derived2::f1.
+ // CHECK: %[[D2_1:[0-9]+]] = ptrtoint %struct.Derived2* %d2 to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED2_1]] {{.*}}, i{{[0-9]+}} %[[D2_1]]
+}
+
+// CHECK-LABEL: define void @_Z2t3v
+void t3() {
+ Derived2 d2;
+ static_cast<Base2 *>(&d2)->f1(); //< Devirt Base2::f1 to Derived2::f1.
+ // CHECK: %[[D2_2:[0-9]+]] = ptrtoint %struct.Derived2* %d2 to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED2_2]] {{.*}}, i{{[0-9]+}} %[[D2_2]]
+}
+
+// CHECK-LABEL: define void @_Z2t4v
+void t4() {
+ Base1 p;
+ Derived3 *badp = static_cast<Derived3 *>(&p); //< Check that &p isa Derived3.
+ // CHECK: %[[P1:[0-9]+]] = ptrtoint %struct.Derived3* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]] {{.*}}, i{{[0-9]+}} %[[P1]]
+
+ static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.
+ // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
+}
+
+// CHECK-LABEL: define void @_Z2t5v
+void t5() {
+ Base1 p;
+ Derived4 *badp = static_cast<Derived4 *>(&p); //< Check that &p isa Derived4.
+ // CHECK: %[[P1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]] {{.*}}, i{{[0-9]+}} %[[P1]]
+
+ static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.
+ // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
+}
diff --git a/test/CodeGenCXX/ubsan-vtable-checks.cpp b/test/CodeGenCXX/ubsan-vtable-checks.cpp
new file mode 100644
index 000000000000..80af77d4ea6d
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-vtable-checks.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
+struct T {
+ virtual ~T() {}
+ virtual int v() { return 1; }
+};
+
+struct U : T {
+ ~U();
+ virtual int v() { return 2; }
+};
+
+U::~U() {}
+
+// ITANIUM: define i32 @_Z5get_vP1T
+// MSABI: define i32 @"\01?get_v
+int get_v(T* t) {
+ // First, we check that vtable is not loaded before a type check.
+ // CHECK-NULL-NOT: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ // CHECK-NULL: [[UBSAN_CMP_RES:%[0-9]+]] = icmp ne %struct.T* %{{[_a-z0-9]+}}, null
+ // CHECK-NULL-NEXT: br i1 [[UBSAN_CMP_RES]], label %{{.*}}, label %{{.*}}
+ // CHECK-NULL: call void @__ubsan_handle_type_mismatch_abort
+ // Second, we check that vtable is actually loaded once the type check is done.
+ // CHECK-NULL: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ return t->v();
+}
+
+// ITANIUM: define void @_Z9delete_itP1T
+// MSABI: define void @"\01?delete_it
+void delete_it(T *t) {
+ // First, we check that vtable is not loaded before a type check.
+ // CHECK-VPTR-NOT: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ // CHECK-VPTR: br i1 {{.*}} label %{{.*}}
+ // CHECK-VPTR: call void @__ubsan_handle_dynamic_type_cache_miss_abort
+ // Second, we check that vtable is actually loaded once the type check is done.
+ // CHECK-VPTR: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ delete t;
+}
diff --git a/test/CodeGenCXX/uncopyable-args.cpp b/test/CodeGenCXX/uncopyable-args.cpp
index c1d284a74185..307a5cf11b6b 100644
--- a/test/CodeGenCXX/uncopyable-args.cpp
+++ b/test/CodeGenCXX/uncopyable-args.cpp
@@ -204,3 +204,77 @@ void bar() {
// WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
}
+
+namespace definition_only {
+struct A {
+ A();
+ A(A &&o);
+ void *p;
+};
+void *foo(A a) { return a.p; }
+// WIN64-LABEL: define i8* @"\01?foo@definition_only@@YAPEAXUA@1@@Z"(%"struct.definition_only::A"*
+}
+
+namespace deleted_by_member {
+struct B {
+ B();
+ B(B &&o);
+ void *p;
+};
+struct A {
+ A();
+ B b;
+};
+void *foo(A a) { return a.b.p; }
+// WIN64-LABEL: define i8* @"\01?foo@deleted_by_member@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member::A"*
+}
+
+namespace deleted_by_base {
+struct B {
+ B();
+ B(B &&o);
+ void *p;
+};
+struct A : B {
+ A();
+};
+void *foo(A a) { return a.p; }
+// WIN64-LABEL: define i8* @"\01?foo@deleted_by_base@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base::A"*
+}
+
+namespace deleted_by_member_copy {
+struct B {
+ B();
+ B(const B &o) = delete;
+ void *p;
+};
+struct A {
+ A();
+ B b;
+};
+void *foo(A a) { return a.b.p; }
+// WIN64-LABEL: define i8* @"\01?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member_copy::A"*
+}
+
+namespace deleted_by_base_copy {
+struct B {
+ B();
+ B(const B &o) = delete;
+ void *p;
+};
+struct A : B {
+ A();
+};
+void *foo(A a) { return a.p; }
+// WIN64-LABEL: define i8* @"\01?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base_copy::A"*
+}
+
+namespace explicit_delete {
+struct A {
+ A();
+ A(const A &o) = delete;
+ void *p;
+};
+// WIN64-LABEL: define i8* @"\01?foo@explicit_delete@@YAPEAXUA@1@@Z"(%"struct.explicit_delete::A"*
+void *foo(A a) { return a.p; }
+}
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index 735dc6163990..fc4e0d3a55e0 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
struct A {
virtual ~A();
@@ -315,6 +315,14 @@ namespace PR20256 {
// CHECK: }
}
+// CHECK-LABEL: define {{.*}}@_Z20explicitly_defaultedv
+int explicitly_defaulted() {
+ struct A { A() = default; int n; };
+ // CHECK: call void @llvm.memset
+ A a = A();
+ return a.n;
+} // CHECK-LABEL: }
+
// CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp
index 554e80d3cf21..b2f2b4f2b319 100644
--- a/test/CodeGenCXX/virtual-base-cast.cpp
+++ b/test/CodeGenCXX/virtual-base-cast.cpp
@@ -82,4 +82,4 @@ BB* d() { return y; }
// MSVC: add nsw i32 4, %[[offset]]
// MSVC: }
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
index e13adfcc85cf..2e63daac31de 100644
--- a/test/CodeGenCXX/virtual-destructor-calls.cpp
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s
struct Member {
~Member();
diff --git a/test/CodeGenCXX/virtual-function-calls.cpp b/test/CodeGenCXX/virtual-function-calls.cpp
index 0a6fc6b3f284..22944d94ca88 100644
--- a/test/CodeGenCXX/virtual-function-calls.cpp
+++ b/test/CodeGenCXX/virtual-function-calls.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - -fstrict-vtable-pointers -O1 | FileCheck --check-prefix=CHECK-INVARIANT %s
// PR5021
namespace PR5021 {
@@ -42,10 +43,14 @@ namespace VirtualNoreturn {
[[noreturn]] virtual void f();
};
- // CHECK: @_ZN15VirtualNoreturn1f
+ // CHECK-LABEL: @_ZN15VirtualNoreturn1f
+ // CHECK-INVARIANT-LABEL: define void @_ZN15VirtualNoreturn1f
void f(A *p) {
p->f();
// CHECK: call {{.*}}void %{{[^#]*$}}
// CHECK-NOT: unreachable
+ // CHECK-INVARIANT: load {{.*}} !invariant.load ![[EMPTY_NODE:[0-9]+]]
}
}
+
+// CHECK-INVARIANT: ![[EMPTY_NODE]] = !{}
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 7c0757b2829a..6ea234807ec2 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
// The trickery with optimization in the run line is to get IR
// generation to emit available_externally function bodies, but not
diff --git a/test/CodeGenCXX/vla-lambda-capturing.cpp b/test/CodeGenCXX/vla-lambda-capturing.cpp
index 44b6a2506d14..5081f1447d27 100644
--- a/test/CodeGenCXX/vla-lambda-capturing.cpp
+++ b/test/CodeGenCXX/vla-lambda-capturing.cpp
@@ -125,11 +125,11 @@ int main() {
// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]]
// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]]
+// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF]]
// CHECK: [[N:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]]
-// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
-// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
// CHECK: [[ELEM_OFFSET:%.+]] = mul {{.*}} i{{[0-9]+}} [[N]], [[SIZE1]]
// CHECK: [[ELEM_ADDR:%.+]] = getelementptr inbounds [[INTPTR_T]], [[INTPTR_T]]* [[BUFFER1_ADDR]], i{{[0-9]+}} [[ELEM_OFFSET]]
// CHECK: [[SIZEOF:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]]
diff --git a/test/CodeGenCXX/vtable-align.cpp b/test/CodeGenCXX/vtable-align.cpp
index f1f10c07df2d..1b82cbc085c9 100644
--- a/test/CodeGenCXX/vtable-align.cpp
+++ b/test/CodeGenCXX/vtable-align.cpp
@@ -9,6 +9,6 @@ struct A {
void A::f() {}
-// CHECK-32: @_ZTV1A = unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)], align 4
+// CHECK-32: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 4
-// CHECK-64: @_ZTV1A = unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)], align 8
+// CHECK-64: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 8
diff --git a/test/CodeGenCXX/vtable-assume-load.cpp b/test/CodeGenCXX/vtable-assume-load.cpp
index 819b09d70e3d..b0857c29c654 100644
--- a/test/CodeGenCXX/vtable-assume-load.cpp
+++ b/test/CodeGenCXX/vtable-assume-load.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions -fstrict-vtable-pointers
-// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
// FIXME: Assume load should not require -fstrict-vtable-pointers
// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
@@ -27,9 +27,9 @@ 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, i32 0, i32 2)
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test11AE, i32 0, inrange i32 0, i32 2)
// CHECK1: call void @llvm.assume(i1 %[[CMP]])
-// CHECK1-LABEL: }
+// CHECK1-LABEL: {{^}}}
void fooA() {
A a;
@@ -39,9 +39,9 @@ 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, i32 0, i32 2)
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test11BE, i32 0, inrange i32 0, i32 2)
// CHECK1: call void @llvm.assume(i1 %[[CMP]])
-// CHECK1-LABEL: }
+// CHECK1-LABEL: {{^}}}
void fooB() {
B b;
@@ -50,7 +50,7 @@ void fooB() {
// there should not be any assumes in the ctor that calls base ctor
// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%"struct.test1::B"*
// CHECK1-NOT: @llvm.assume(
-// CHECK1-LABEL: }
+// CHECK1-LABEL: {{^}}}
}
namespace test2 {
struct A {
@@ -73,18 +73,18 @@ 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, i32 0, i32 2)
+// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* @_ZTVN5test21CE, i32 0, inrange 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, i32 0, i32 5)
+// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* @_ZTVN5test21CE, i32 0, inrange i32 1, i32 2)
// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
// CHECK2: call void @_ZN5test21gEPNS_1AE(
-// CHECK2-LABEL: }
+// CHECK2-LABEL: {{^}}}
void test() {
C c;
@@ -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, i32 0, i32 3)
+// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5test31CE, i32 0, inrange i32 0, i32 3)
// CHECK3: call void @llvm.assume(i1 %[[CMP]])
// CHECK3-LABLEL: }
void test() {
@@ -140,13 +140,13 @@ 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, i32 0, i32 4)
+// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5test41CE, i32 0, inrange 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, i32 0, i32 4)
+// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4)
// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
-// CHECK4-LABEL: }
+// CHECK4-LABEL: {{^}}}
void test() {
C c;
@@ -166,7 +166,7 @@ void g(S &s) { s.foo(); }
// CHECK-MS-LABEL: define void @"\01?test@testMS@@YAXXZ"()
// CHECK-MS: call x86_thiscallcc %"struct.testMS::S"* @"\01??0S@testMS@@QAE@XZ"(
// CHECK-MS-NOT: @llvm.assume
-// CHECK-MS-LABEL: }
+// CHECK-MS-LABEL: {{^}}}
void test() {
S s;
@@ -196,7 +196,7 @@ struct B : A {
// CHECK6-LABEL: call void @_ZN5test61BC1Ev(
// CHECK6-NOT: call void @llvm.assume(
-// CHECK6-LABEL: }
+// CHECK6-LABEL: {{^}}}
void g() {
A *a = new A;
B *b = new B;
@@ -216,7 +216,7 @@ void A::foo() {}
// CHECK7-LABEL: define void @_ZN5test71gEv()
// CHECK7: call void @_ZN5test71AC1Ev(
// CHECK7: call void @llvm.assume(
-// CHECK7-LABEL: }
+// CHECK7-LABEL: {{^}}}
void g() {
A *a = new A();
a->bar();
@@ -259,7 +259,7 @@ struct E : A {
// CHECK8-LABEL: define void @_ZN5test81bEv()
// CHECK8: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
void b() {
B b;
b.bar();
@@ -270,7 +270,7 @@ void b() {
// defined here) it would be correct to refer to it.
// CHECK8-LABEL: define void @_ZN5test81cEv()
// CHECK8-NOT: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
void c() {
C c;
c.bar();
@@ -279,7 +279,7 @@ void c() {
// FIXME: We could generate assumption loads here.
// CHECK8-LABEL: define void @_ZN5test81dEv()
// CHECK8-NOT: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
void d() {
D d;
d.bar();
@@ -287,7 +287,7 @@ void d() {
// CHECK8-LABEL: define void @_ZN5test81eEv()
// CHECK8: call void @llvm.assume(
-// CHECK8-LABEL: }
+// CHECK8-LABEL: {{^}}}
void e() {
E e;
e.bar();
diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp
index f38d177666e6..ae81959a75e9 100644
--- a/test/CodeGenCXX/vtable-available-externally.cpp
+++ b/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-optzns -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index ca5384d6e031..4a47e3c9d2e8 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -1919,6 +1919,8 @@ namespace Test40 {
virtual int i(int);
virtual int i();
};
+ // Force C's vtable to be generated.
+ int C::f() { return 1; }
class D : C {};
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index 0b556d10c3e8..c4ebf75b999a 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -1,6 +1,10 @@
// 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: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++03 -o %t.03
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++11 -o %t.11
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-passes -O3 -emit-llvm -o %t.opt
// RUN: FileCheck %s < %t
+// RUN: FileCheck %s < %t.03
+// RUN: FileCheck %s < %t.11
// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
namespace {
@@ -33,6 +37,11 @@ void D::f() { }
static struct : D { } e;
+// Force 'e' to be constructed and therefore have a vtable defined.
+void use_e() {
+ e.f();
+}
+
// The destructor is the key function.
template<typename T>
struct E {
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index 130a55cf6218..49c8de4ea4f5 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, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1B, i32 0, inrange 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, i32 0, i32 2) to i32 (...)**)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1B, i32 0, inrange 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 7ff93dd451c9..a5f7802577c8 100644
--- a/test/CodeGenCXX/vtt-layout.cpp
+++ b/test/CodeGenCXX/vtt-layout.cpp
@@ -78,11 +78,12 @@ namespace Test6 {
}
}
-// 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, 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: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3) to i8*)]
+// CHECK: @_ZTVN5Test51AE = unnamed_addr constant { [4 x i8*] } { [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*] } { [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, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*)]
+// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*)]
+// CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr constant { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] } { [6 x i8*] [i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* null, i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [8 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 56 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::V3"*)* @_ZN5Test42V31gEv to i8*)], [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [4 x i8*] [i8* null, i8* inttoptr (i64 -56 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::A2"*)* @_ZN5Test42A21fEv to i8*)], [4 x i8*] [i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)] }
+// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3) to i8*)]
// CHECK: declare void @__cxa_pure_virtual() unnamed_addr
// CHECK: declare void @__cxa_deleted_virtual() unnamed_addr
diff --git a/test/CodeGenCXX/wasm-args-returns.cpp b/test/CodeGenCXX/wasm-args-returns.cpp
index 2b80430014d0..24adc8e08761 100644
--- a/test/CodeGenCXX/wasm-args-returns.cpp
+++ b/test/CodeGenCXX/wasm-args-returns.cpp
@@ -14,7 +14,7 @@
struct one_field { double d; };
test(one_field);
-// CHECK: define double @_Z7forward9one_field(double %{{.*}})
+// CHECK: define double @_Z7forward9one_field(double returned %{{.*}})
//
// CHECK: define void @_Z14test_one_fieldv()
// CHECK: %[[call:.*]] = tail call double @_Z13def_one_fieldv()
@@ -89,7 +89,7 @@ struct one_bitfield {
int d:3;
};
test(one_bitfield);
-// CHECK: define i32 @_Z7forward12one_bitfield(i32 %{{.*}})
+// CHECK: define i32 @_Z7forward12one_bitfield(i32 returned %{{.*}})
//
// CHECK: define void @_Z17test_one_bitfieldv()
// CHECK: %[[call:.*]] = tail call i32 @_Z16def_one_bitfieldv()
diff --git a/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp b/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp
new file mode 100644
index 000000000000..c2f2a0773e90
--- /dev/null
+++ b/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-IA
+
+template <typename>
+struct s {};
+
+template <typename T_>
+class t : s<T_> {};
+
+extern template class t<char>;
+template class __declspec(dllexport) t<char>;
+
+// CHECK-MS: dllexport {{.*}} @"\01??4?$t@D@@QAEAAV0@ABV0@@Z"
+// CHECK-MS: dllexport {{.*}} @"\01??4?$s@D@@QAEAAU0@ABU0@@Z"
+
+// CHECK-IA: dllexport {{.*}} @_ZN1tIcEaSERKS0_
+// CHECK-IA: dllexport {{.*}} @_ZN1sIcEaSERKS0_
+
diff --git a/test/CodeGenCXX/windows-itanium-dllexport.cpp b/test/CodeGenCXX/windows-itanium-dllexport.cpp
new file mode 100644
index 000000000000..92cca2444287
--- /dev/null
+++ b/test/CodeGenCXX/windows-itanium-dllexport.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fdeclspec %s -o - | FileCheck %s
+
+struct __declspec(dllexport) s {
+ void f() {}
+};
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1saSERKS_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1s1fEv
+
+template <class T>
+class c {
+ void f() {}
+};
+
+template class __declspec(dllexport) c<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv
+
+extern template class c<char>;
+template class __declspec(dllexport) c<char>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv
+
+c<double> g;
+template class __declspec(dllexport) c<double>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
diff --git a/test/CodeGenCXX/windows-itanium-type-info.cpp b/test/CodeGenCXX/windows-itanium-type-info.cpp
new file mode 100644
index 000000000000..ad89318f599e
--- /dev/null
+++ b/test/CodeGenCXX/windows-itanium-type-info.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -fcxx-exceptions -fno-rtti -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-EH-IMPORT
+
+namespace __cxxabiv1 {
+class __declspec(dllexport) __fundamental_type_info {
+public:
+ virtual ~__fundamental_type_info();
+};
+
+__fundamental_type_info::~__fundamental_type_info() {}
+}
+
+struct __declspec(dllimport) base {
+ virtual void method();
+};
+struct __declspec(dllexport) derived : base {
+ virtual ~derived();
+};
+derived::~derived() {
+ method();
+}
+
+void f() {
+ throw base();
+}
+
+// CHECK-DAG: @_ZTIi = dllexport constant
+// CHECK-DAG: @_ZTSi = dllexport constant
+
+// CHECK-DAG: @_ZTI7derived = dllexport constant
+// CHECK-DAG: @_ZTS7derived = dllexport constant
+// CHECK-DAG: @_ZTV7derived = dllexport unnamed_addr constant
+
+// CHECK-DAG: @_ZTI4base = external dllimport constant
+// CHECK-DAG: @_ZTS4base = external dllimport constant
+// CHECK-NOT: @_ZTV4base = external dllimport constant
+
+// CHECK-EH-IMPORT: @_ZTS4base = linkonce_odr constant
+// CHECK-EH-IMPORT: @_ZTI4base = linkonce_odr constant
+