Emit vtable info.

llvm-svn: 94751
This commit is contained in:
Devang Patel 2010-01-28 18:11:52 +00:00
parent a424b9fbd1
commit 84033fb240
2 changed files with 82 additions and 1 deletions

View File

@ -681,6 +681,72 @@ CollectCXXBases(const CXXRecordDecl *Decl,
}
}
/// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DICompileUnit Unit) {
if (!VTablePtrType.isNull())
return VTablePtrType;
ASTContext &Context = CGM.getContext();
/* Function type */
llvm::SmallVector<llvm::DIDescriptor, 16> STys;
STys.push_back(getOrCreateType(Context.IntTy, Unit));
llvm::DIArray SElements =
DebugFactory.GetOrCreateArray(STys.data(), STys.size());
llvm::DIType SubTy =
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
Unit, "", llvm::DICompileUnit(),
0, 0, 0, 0, 0, llvm::DIType(), SElements);
unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
llvm::DIType vtbl_ptr_type
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
Unit, "__vtbl_ptr_type", llvm::DICompileUnit(),
0, Size, 0, 0, 0, SubTy);
VTablePtrType = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
Unit, "", llvm::DICompileUnit(),
0, Size, 0, 0, 0, vtbl_ptr_type);
return VTablePtrType;
}
/// getVtableName - Get vtable name for the given Class.
llvm::StringRef CGDebugInfo::getVtableName(const CXXRecordDecl *Decl) {
// Otherwise construct gdb compatible name name.
std::string Name = "_vptr$" + Decl->getNameAsString();
// Copy this name on the side and use its reference.
char *StrPtr = FunctionNames.Allocate<char>(Name.length());
memcpy(StrPtr, Name.data(), Name.length());
return llvm::StringRef(StrPtr, Name.length());
}
/// CollectVtableInfo - If the C++ class has vtable info then insert appropriate
/// debug info entry in EltTys vector.
void CGDebugInfo::
CollectVtableInfo(const CXXRecordDecl *Decl,
llvm::DICompileUnit Unit,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(Decl);
// If there is a primary base then it will hold vtable info.
if (RL.getPrimaryBase())
return;
// If this class is not dynamic then there is not any vtable info to collect.
if (!Decl->isDynamicClass())
return;
unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
llvm::DIType VPTR
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
getVtableName(Decl), llvm::DICompileUnit(),
0, Size, 0, 0, 0,
getOrCreateVTablePtrType(Unit));
EltTys.push_back(VPTR);
}
/// CreateType - get structure or union type.
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
llvm::DICompileUnit Unit) {
@ -737,9 +803,12 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
// Convert all the elements.
llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(Decl);
if (CXXDecl)
CollectVtableInfo(CXXDecl, Unit, EltTys);
CollectRecordFields(Decl, Unit, EltTys);
llvm::MDNode *ContainingType = NULL;
if (CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(Decl)) {
if (CXXDecl) {
CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl);
CollectCXXBases(CXXDecl, Unit, EltTys, FwdDecl);

View File

@ -47,6 +47,8 @@ class CGDebugInfo {
llvm::DIFactory DebugFactory;
SourceLocation CurLoc, PrevLoc;
llvm::DIType VTablePtrType;
/// CompileUnitCache - Cache of previously constructed CompileUnits.
llvm::DenseMap<unsigned, llvm::DICompileUnit> CompileUnitCache;
@ -85,6 +87,7 @@ class CGDebugInfo {
llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DICompileUnit U);
llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DICompileUnit Unit);
llvm::DIType getOrCreateVTablePtrType(llvm::DICompileUnit Unit);
llvm::DIType CreatePointerLikeType(unsigned Tag,
const Type *Ty, QualType PointeeTy,
@ -106,6 +109,11 @@ class CGDebugInfo {
void CollectRecordFields(const RecordDecl *Decl, llvm::DICompileUnit U,
llvm::SmallVectorImpl<llvm::DIDescriptor> &E);
void CollectVtableInfo(const CXXRecordDecl *Decl,
llvm::DICompileUnit Unit,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys);
public:
CGDebugInfo(CodeGenModule &CGM);
~CGDebugInfo();
@ -181,6 +189,10 @@ private:
/// name is constructred on demand (e.g. C++ destructor) then the name
/// is stored on the side.
llvm::StringRef getFunctionName(const FunctionDecl *FD);
/// getVtableName - Get vtable name for the given Class.
llvm::StringRef getVtableName(const CXXRecordDecl *Decl);
};
} // namespace CodeGen
} // namespace clang