summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp59
1 files changed, 57 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 2b54e7bd67a..92e442d3312 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -37,6 +37,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
@@ -1085,9 +1086,14 @@ public:
const CGBlockInfo &blockInfo) override;
llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
const CGBlockInfo &blockInfo) override;
+ std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,
+ const CGBlockInfo &blockInfo) override;
llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
QualType T) override;
+
+private:
+ void fillRunSkipBlockVars(CodeGenModule &CGM, const CGBlockInfo &blockInfo);
};
namespace {
@@ -2795,8 +2801,44 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
return getConstantGEP(VMContext, Entry, 0, 0);
}
-llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
- const CGBlockInfo &blockInfo) {
+static std::string getBlockLayoutInfoString(
+ const SmallVectorImpl<CGObjCCommonMac::RUN_SKIP> &RunSkipBlockVars,
+ bool HasCopyDisposeHelpers) {
+ std::string Str;
+ for (const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
+ if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
+ // Copy/dispose helpers don't have any information about
+ // __unsafe_unretained captures, so unconditionally concatenate a string.
+ Str += "u";
+ } else if (HasCopyDisposeHelpers) {
+ // Information about __strong, __weak, or byref captures has already been
+ // encoded into the names of the copy/dispose helpers. We have to add a
+ // string here only when the copy/dispose helpers aren't generated (which
+ // happens when the block is non-escaping).
+ continue;
+ } else {
+ switch (R.opcode) {
+ case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
+ Str += "s";
+ break;
+ case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
+ Str += "r";
+ break;
+ case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
+ Str += "w";
+ break;
+ default:
+ continue;
+ }
+ }
+ Str += llvm::to_string(R.block_var_bytepos.getQuantity());
+ Str += "l" + llvm::to_string(R.block_var_size.getQuantity());
+ }
+ return Str;
+}
+
+void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
+ const CGBlockInfo &blockInfo) {
assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
RunSkipBlockVars.clear();
@@ -2845,9 +2887,22 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
fieldOffset, fieldSize);
}
+}
+
+llvm::Constant *
+CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
+ const CGBlockInfo &blockInfo) {
+ fillRunSkipBlockVars(CGM, blockInfo);
return getBitmapBlockLayout(false);
}
+std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
+ const CGBlockInfo &blockInfo) {
+ fillRunSkipBlockVars(CGM, blockInfo);
+ return getBlockLayoutInfoString(RunSkipBlockVars,
+ blockInfo.needsCopyDisposeHelpers());
+}
+
llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
QualType T) {
assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
OpenPOWER on IntegriCloud