// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY
// Test tail call behavior when a swiftasynccall function is called
// from another swiftasynccall function.
// CHECK-LABEL: swifttailcc void {{.*}}async_leaf1{{.*}}(i8* swiftasync
SWIFTASYNCCALL void
// CHECK-LABEL: swifttailcc void {{.*}}async_leaf2{{.*}}(i8* swiftasync
SWIFTASYNCCALL void
// CHECK-LABEL: swifttailcc void {{.*}}async_branch{{.*}}i8* swiftasync
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
// CHECK-NEXT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
// CHECK-NEXT: ret void
SWIFTASYNCCALL void
// CHECK-LABEL: swifttailcc void {{.*}}async_not_all_tail
// CHECK-NOT: musttail call swifttailcc void @{{.*}}async_leaf1
// CHECK: call swifttailcc void @{{.*}}async_leaf1
// CHECK-NOT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
// CHECK-NEXT: ret void
SWIFTASYNCCALL void
// CHECK-LABEL: swifttailcc void {{.*}}async_loop
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
// CHECK-NEXT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
// CHECK-NEXT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_loop
// CHECK-NEXT: ret void
SWIFTASYNCCALL void
// Forward-declaration + mutual recursion is okay.
SWIFTASYNCCALL void ;
// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop1
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
// CHECK-NEXT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
// CHECK-NEXT: ret void
// There is some bugginess around FileCheck's greediness/matching,
// so skipping the check for async_mutual_loop2 here.
SWIFTASYNCCALL void
// CHECK-LABEL: swifttailcc void {{.*}}async_mutual_loop2
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf1
// CHECK-NEXT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_leaf2
// CHECK-NEXT: ret void
// CHECK: musttail call swifttailcc void @{{.*}}async_mutual_loop1
// CHECK-NEXT: ret void
SWIFTASYNCCALL void
// When swiftasynccall functions are called by non-swiftasynccall functions,
// the call isn't marked as a tail call.
// CHECK-LABEL: swiftcc i8 {{.*}}sync_calling_async
// CHECK-NOT: tail call
// CHECK: call swifttailcc void @{{.*}}async_branch
// CHECK-NOT: tail call
// CHECK: call swifttailcc void @{{.*}}async_loop
SWIFTCALL char
// CHECK-LABEL: i8 {{.*}}c_calling_async
// CHECK-NOT: tail call
// CHECK: call swifttailcc void @{{.*}}async_branch
// CHECK-NOT: tail call
// CHECK: call swifttailcc void @{{.*}}async_loop
char
;
SWIFTASYNCCALL void = &S::async_leaf_method;
// CPPONLY-LABEL: swifttailcc void {{.*}}async_struct_field_and_methods
// CPPONLY: musttail call swifttailcc void %{{[0-9]+}}
// CPPONLY: musttail call swifttailcc void @{{.*}}async_nonleaf_method1
// CPPONLY: musttail call swifttailcc void %{{[0-9]+}}
// CPPONLY: musttail call swifttailcc void @{{.*}}async_nonleaf_method2
// CPPONLY-NOT: musttail call swifttailcc void @{{.*}}async_leaf_method
// ^ TODO: Member pointers should also work.
SWIFTASYNCCALL void
// CPPONLY-LABEL: define{{.*}} swifttailcc void @{{.*}}async_nonleaf_method1
// CPPONLY: musttail call swifttailcc void @{{.*}}async_leaf_method
// CPPONLY-LABEL: define{{.*}} swifttailcc void @{{.*}}async_nonleaf_method2
// CPPONLY: musttail call swifttailcc void @{{.*}}async_leaf_method