diff options
author | Adrian Prantl <aprantl@apple.com> | 2013-03-29 19:20:29 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2013-03-29 19:20:29 +0000 |
commit | e86fcc46f560b8e0e13e13a7a1854658b231b2ea (patch) | |
tree | 2cbc6fdfcc1f0ad245091ce4ec6989f698c7a82c /lib/CodeGen/CGDebugInfo.cpp | |
parent | 073f5e87dc936c906dde5ae21ebed3c59ce3d8e2 (diff) |
Improvement on r177086.
* Let DIType for block-captured self to point to the completed cached
interface type.
rdar://problem/12767564
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178360 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 5e350a9961..2529ec8dc2 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -2148,8 +2148,9 @@ llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl *D, // First element is always return type. For 'void' functions it is NULL. Elts.push_back(getOrCreateType(OMethod->getResultType(), F)); // "self" pointer is always first argument. - llvm::DIType SelfTy = getOrCreateType(OMethod->getSelfDecl()->getType(), F); - Elts.push_back(DBuilder.createObjectPointerType(SelfTy)); + QualType SelfDeclTy = OMethod->getSelfDecl()->getType(); + llvm::DIType SelfTy = getOrCreateType(SelfDeclTy, F); + Elts.push_back(CreateSelfType(SelfDeclTy, SelfTy)); // "_cmd" pointer is always second argument. llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F); Elts.push_back(DBuilder.createArtificialType(CmdTy)); @@ -2581,6 +2582,19 @@ void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, 0, Builder); } +/// Look up the completed type for a self pointer in the TypeCache and +/// create a copy of it with the ObjectPointer and Artificial flags +/// set. If the type is not cached, a new one is created. This should +/// never happen though, since creating a type for the implicit self +/// argument implies that we already parsed the interface definition +/// and the ivar declarations in the implementation. +llvm::DIType CGDebugInfo::CreateSelfType(const QualType &QualTy, llvm::DIType Ty) { + llvm::DIType CachedTy = getTypeOrNull(QualTy); + if (CachedTy.Verify()) Ty = CachedTy; + else DEBUG(llvm::dbgs() << "No cached type for self."); + return DBuilder.createObjectPointerType(Ty); +} + void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD, llvm::Value *Storage, CGBuilderTy &Builder, @@ -2604,7 +2618,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD, // Self is passed along as an implicit non-arg variable in a // block. Mark it as the object pointer. if (isa<ImplicitParamDecl>(VD) && VD->getName() == "self") - Ty = DBuilder.createObjectPointerType(Ty); + Ty = CreateSelfType(VD->getType(), Ty); // Get location information. unsigned Line = getLineNumber(VD->getLocation()); |