From 2ed8f000869103b1adc05d6bc4c635604b6e66a7 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 27 Aug 2010 17:47:47 +0000 Subject: [PATCH] Debug info for friends! Patch originally by Alexander Herz. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112275 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 62 +++++++++++++++++++++------ lib/CodeGen/CGDebugInfo.h | 6 +++ test/CodeGenCXX/debug-info-friend.cpp | 11 +++++ 3 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 test/CodeGenCXX/debug-info-friend.cpp diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 4873587a41..939b6f768d 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -15,6 +15,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" @@ -602,9 +603,12 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, 0), Unit); - // Static methods do not need "this" pointer argument. - if (Method->isStatic()) - return FnTy; + unsigned BFlags=0; + AccessSpecifier Access = Method->getAccess(); + if (Access == clang::AS_private) + BFlags |= llvm::DIType::FlagPrivate; + else if (Access == clang::AS_protected) + BFlags |= llvm::DIType::FlagProtected; // Add "this" pointer. @@ -616,15 +620,18 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, // First element is always return type. For 'void' functions it is NULL. Elts.push_back(Args.getElement(0)); - // "this" pointer is always first argument. - ASTContext &Context = CGM.getContext(); - QualType ThisPtr = - Context.getPointerType(Context.getTagDeclType(Method->getParent())); - llvm::DIType ThisPtrType = - DebugFactory.CreateArtificialType(getOrCreateType(ThisPtr, Unit)); - - TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType; - Elts.push_back(ThisPtrType); + if (!Method->isStatic()) + { + // "this" pointer is always first argument. + ASTContext &Context = CGM.getContext(); + QualType ThisPtr = + Context.getPointerType(Context.getTagDeclType(Method->getParent())); + llvm::DIType ThisPtrType = + DebugFactory.CreateArtificialType(getOrCreateType(ThisPtr, Unit)); + + TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType; + Elts.push_back(ThisPtrType); + } // Copy rest of the arguments. for (unsigned i = 1, e = Args.getNumElements(); i != e; ++i) @@ -716,6 +723,34 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, } } +/// CollectCXXFriends - A helper function to collect debug info for +/// C++ base classes. This is used while creating debug info entry for +/// a Record. +void CGDebugInfo:: +CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit, + llvm::SmallVectorImpl &EltTys, + llvm::DIType RecordTy) { + + for (CXXRecordDecl::friend_iterator BI = RD->friend_begin(), + BE = RD->friend_end(); BI != BE; ++BI) { + + TypeSourceInfo *TInfo = (*BI)->getFriendType(); + if(TInfo) + { + llvm::DIType Ty = getOrCreateType(TInfo->getType(), Unit); + + llvm::DIType DTy = + DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_friend, + RecordTy, llvm::StringRef(), + Unit, 0, 0, 0, + 0, 0, Ty); + + EltTys.push_back(DTy); + } + + } +} + /// CollectCXXBases - A helper function to collect debug info for /// C++ base classes. This is used while creating debug info entry for /// a Record. @@ -910,6 +945,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, llvm::MDNode *ContainingType = NULL; if (CXXDecl) { CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl); + CollectCXXFriends(CXXDecl, Unit, EltTys, FwdDecl); // A class's primary base or the class itself contains the vtable. const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); @@ -1853,7 +1889,7 @@ CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl, getContextDescriptor(dyn_cast(NSDecl->getDeclContext()), Unit); llvm::DINameSpace NS = DebugFactory.CreateNameSpace(Context, NSDecl->getName(), - llvm::DIFile(Unit), LineNo); + llvm::DIFile(Unit), LineNo); NameSpaceCache[NSDecl] = llvm::WeakVH(NS); return NS; } diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 2d8efcee85..fce66b25af 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -111,6 +111,12 @@ class CGDebugInfo { llvm::DIFile F, llvm::SmallVectorImpl &E, llvm::DIType T); + + void CollectCXXFriends(const CXXRecordDecl *Decl, + llvm::DIFile F, + llvm::SmallVectorImpl &EltTys, + llvm::DIType RecordTy); + void CollectCXXBases(const CXXRecordDecl *Decl, llvm::DIFile F, llvm::SmallVectorImpl &EltTys, diff --git a/test/CodeGenCXX/debug-info-friend.cpp b/test/CodeGenCXX/debug-info-friend.cpp new file mode 100644 index 0000000000..c50f281a3b --- /dev/null +++ b/test/CodeGenCXX/debug-info-friend.cpp @@ -0,0 +1,11 @@ +// RUN: %clang -fverbose-asm -S -g %s -o - | grep DW_TAG_friend + +class MyFriend; + +class SomeClass +{ + friend class MyFriend; +}; + +SomeClass sc; + -- 2.40.0