BD->setIsVariadic(Record.readInt());
BD->setBlockMissingReturnType(Record.readInt());
BD->setIsConversionFromLambda(Record.readInt());
+ BD->setDoesNotEscape(Record.readInt());
bool capturesCXXThis = Record.readInt();
unsigned numCaptures = Record.readInt();
Record.push_back(D->isVariadic());
Record.push_back(D->blockMissingReturnType());
Record.push_back(D->isConversionFromLambda());
+ Record.push_back(D->doesNotEscape());
Record.push_back(D->capturesCXXThis());
Record.push_back(D->getNumCaptures());
for (const auto &capture : D->captures()) {
--- /dev/null
+// RUN: %clang_cc1 -x c++-header -emit-pch -O1 -fblocks -fno-escaping-block-tail-calls -o %t %S/no-escaping-block-tail-calls.h
+// RUN: %clang_cc1 -include-pch %t -emit-llvm -O1 -fblocks -fno-escaping-block-tail-calls -o - %s | FileCheck %s
+
+// Check that -fno-escaping-block-tail-calls doesn't disable tail-call
+// optimization if the block is non-escaping.
+
+// CHECK-LABEL: define internal i32 @___ZN1S1mEv_block_invoke(
+// CHECK: %[[CALL:.*]] = tail call i32 @_ZN1S3fooER2S0(
+// CHECK-NEXT: ret i32 %[[CALL]]
+
+void test() {
+ S s;
+ s.m();
+}
--- /dev/null
+typedef int (^BlockTy)(void);
+
+struct S0 {
+ int a;
+};
+
+struct S {
+ int i;
+ void func(BlockTy __attribute__((noescape)));
+ int foo(S0 &);
+
+ void m() {
+ __block S0 x;
+ func(^{ return foo(x); });
+ }
+};