From 84033fb2409717633efc522e5aad7d238aef1b74 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Thu, 28 Jan 2010 18:11:52 +0000 Subject: [PATCH] Emit vtable info. llvm-svn: 94751 --- clang/lib/CodeGen/CGDebugInfo.cpp | 71 ++++++++++++++++++++++++++++++- clang/lib/CodeGen/CGDebugInfo.h | 12 ++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index d55ddb7c2dc4..f9a40cb0b5fa 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -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 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(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 &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 EltTys; + const CXXRecordDecl *CXXDecl = dyn_cast(Decl); + if (CXXDecl) + CollectVtableInfo(CXXDecl, Unit, EltTys); CollectRecordFields(Decl, Unit, EltTys); llvm::MDNode *ContainingType = NULL; - if (CXXRecordDecl *CXXDecl = dyn_cast(Decl)) { + if (CXXDecl) { CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl); CollectCXXBases(CXXDecl, Unit, EltTys, FwdDecl); diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 536241310043..ac75ac02319e 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -47,6 +47,8 @@ class CGDebugInfo { llvm::DIFactory DebugFactory; SourceLocation CurLoc, PrevLoc; + + llvm::DIType VTablePtrType; /// CompileUnitCache - Cache of previously constructed CompileUnits. llvm::DenseMap 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 &E); + + void CollectVtableInfo(const CXXRecordDecl *Decl, + llvm::DICompileUnit Unit, + llvm::SmallVectorImpl &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