diff options
Diffstat (limited to 'clang/lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 59 |
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); |