diff options
author | Mike Stump <mrs@apple.com> | 2009-09-22 02:12:52 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-09-22 02:12:52 +0000 |
commit | 39605b4eab472a37cec287f9d4663805e60346f3 (patch) | |
tree | 5db6475b48f715470975dd4bf9f080edd39fd89c /lib/CodeGen/CGDebugInfo.cpp | |
parent | e4feb834fb1a6b03291ed78fd32d13729b5a3c4a (diff) |
Improve debug info generation for __block variables.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82508 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 1bd0918f1a..6f5bb15d45 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -918,7 +918,139 @@ void CGDebugInfo::EmitDeclare(const VarDecl *Decl, unsigned Tag, return; llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation()); - llvm::DIType Ty = getOrCreateType(Decl->getType(), Unit); + QualType Type = Decl->getType(); + llvm::DIType Ty = getOrCreateType(Type, Unit); + if (Decl->hasAttr<BlocksAttr>()) { + llvm::DICompileUnit DefUnit; + unsigned Tag = llvm::dwarf::DW_TAG_structure_type; + + llvm::SmallVector<llvm::DIDescriptor, 5> EltTys; + + llvm::DIType FieldTy; + + QualType FType; + uint64_t FieldSize, FieldOffset; + unsigned FieldAlign; + + llvm::DIArray Elements; + llvm::DIType EltTy; + + // Build up structure for the byref. See BuildByRefType. + FieldOffset = 0; + FType = M->getContext().getPointerType(M->getContext().VoidTy); + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + "__isa", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + + FType = M->getContext().getPointerType(M->getContext().VoidTy); + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + "__forwarding", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + + FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty; + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + "__flags", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + + FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty; + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + "__size", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + + bool HasCopyAndDispose = M->BlockRequiresCopying(Type); + if (HasCopyAndDispose) { + FType = M->getContext().getPointerType(M->getContext().VoidTy); + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + "__copy_helper", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + + FType = M->getContext().getPointerType(M->getContext().VoidTy); + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + "__destroy_helper", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + } + + unsigned Align = M->getContext().getDeclAlignInBytes(Decl); + if (Align > M->getContext().Target.getPointerAlign(0) / 8) { + unsigned AlignedOffsetInBytes + = llvm::RoundUpToAlignment(FieldOffset, Align); + unsigned NumPaddingBytes + = AlignedOffsetInBytes = FieldOffset; + + if (NumPaddingBytes > 0) { + llvm::APInt pad(32, NumPaddingBytes); + FType = M->getContext().getConstantArrayType(M->getContext().CharTy, + pad, ArrayType::Normal, 0); + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, + Unit, "", DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + } + } + + FType = Type; + FieldTy = CGDebugInfo::getOrCreateType(FType, Unit); + FieldSize = M->getContext().getTypeSize(FType); + FieldAlign = M->getContext().getTypeAlign(FType); + std::string Name = Decl->getNameAsString(); + + FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, + Name, DefUnit, + 0, FieldSize, FieldAlign, + FieldOffset, 0, FieldTy); + EltTys.push_back(FieldTy); + FieldOffset += FieldSize; + + Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size()); + + unsigned Flags = llvm::DIType::FlagBlockByrefStruct; + + Ty = DebugFactory.CreateCompositeType(Tag, Unit, "", + llvm::DICompileUnit(), + 0, FieldOffset, 0, 0, Flags, + llvm::DIType(), Elements); + } // Get location information. SourceManager &SM = M->getContext().getSourceManager(); |