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 | |
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
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 1 |
2 files changed, 18 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()); diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 30cf56ecc2..3a0df999b5 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -119,6 +119,7 @@ class CGDebugInfo { llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F); llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F); llvm::DIType CreateEnumType(const EnumDecl *ED); + llvm::DIType CreateSelfType(const QualType &QualTy, llvm::DIType Ty); llvm::DIType getTypeOrNull(const QualType); llvm::DIType getCompletedTypeOrNull(const QualType); llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method, |