diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 5 |
4 files changed, 36 insertions, 6 deletions
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 35bff1035e..493e46be47 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -970,6 +970,17 @@ void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { Out << "@interface " << *PID->getClassInterface() << '(' << *PID << ")\n"; + if (PID->ivar_size() > 0) { + Out << "{\n"; + Indentation += Policy.Indentation; + for (ObjCCategoryDecl::ivar_iterator I = PID->ivar_begin(), + E = PID->ivar_end(); I != E; ++I) { + Indent() << I->getType().getAsString(Policy) << ' ' << **I << ";\n"; + } + Indentation -= Policy.Indentation; + Out << "}\n"; + } + VisitDeclContext(PID, false); Out << "@end"; diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 1d8b326d20..d181da2de6 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -428,7 +428,11 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // to get reproducible results. There should probably be an // llvm::array_pod_stable_sort. std::stable_sort(layout.begin(), layout.end()); - + + // Needed for blocks layout info. + info.BlockHeaderForcedGapOffset = info.BlockSize; + info.BlockHeaderForcedGapSize = CharUnits::Zero(); + CharUnits &blockSize = info.BlockSize; info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign); @@ -469,17 +473,22 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, endAlign = getLowBit(blockSize); // ...until we get to the alignment of the maximum field. - if (endAlign >= maxFieldAlign) + if (endAlign >= maxFieldAlign) { + if (li == first) { + // No user field was appended. So, a gap was added. + // Save total gap size for use in block layout bit map. + info.BlockHeaderForcedGapSize = li->Size; + } break; + } } - // Don't re-append everything we just appended. layout.erase(first, li); } } assert(endAlign == getLowBit(blockSize)); - + // At this point, we just have to add padding if the end align still // isn't aligned right. if (endAlign < maxFieldAlign) { @@ -494,7 +503,6 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, assert(endAlign >= maxFieldAlign); assert(endAlign == getLowBit(blockSize)); - // Slam everything else on now. This works because they have // strictly decreasing alignment and we expect that size is always a // multiple of alignment. diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index e63d4b6b1f..0e40478fad 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -211,6 +211,14 @@ public: const BlockExpr *BlockExpression; CharUnits BlockSize; CharUnits BlockAlign; + + // Offset of the gap caused by block header having a smaller + // alignment than the alignment of the block descriptor. This + // is the gap offset before the first capturued field. + CharUnits BlockHeaderForcedGapOffset; + // Gap size caused by aligning first field after block header. + // This could be zero if no forced alignment is required. + CharUnits BlockHeaderForcedGapSize; /// An instruction which dominates the full-expression that the /// block is inside. diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index f4b42bb9b7..d84875bfd5 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -2424,7 +2424,10 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, // Ignore the optional 'this' capture: C++ objects are not assumed // to be GC'ed. - + if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero()) + UpdateRunSkipBlockVars(false, Qualifiers::OCL_None, + blockInfo.BlockHeaderForcedGapOffset, + blockInfo.BlockHeaderForcedGapSize); // Walk the captured variables. for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), ce = blockDecl->capture_end(); ci != ce; ++ci) { |