Improvement on r177086.

* Let DIType for block-captured self to point to the completed cached
  interface type.
rdar://problem/12767564

llvm-svn: 178360
This commit is contained in:
Adrian Prantl
2013-03-29 19:20:29 +00:00
parent 7b8b9b9abf
commit de17db30d8
2 changed files with 18 additions and 3 deletions

View File

@@ -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());

View File

@@ -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,