diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index e20c463355b3..6b2c3c6b6ddb 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -519,6 +519,65 @@ CollectRecordFields(const RecordDecl *Decl, } } +/// CollectCXXMemberFunctions - A helper function to collect debug info for +/// C++ member functions.This is used while creating debug info entry for +/// a Record. +void CGDebugInfo:: +CollectCXXMemberFunctions(const CXXRecordDecl *Decl, + llvm::DICompileUnit Unit, + llvm::SmallVectorImpl &EltTys, + llvm::DICompositeType &RecordTy) { + SourceManager &SM = CGM.getContext().getSourceManager(); + for(CXXRecordDecl::method_iterator I = Decl->method_begin(), + E = Decl->method_end(); I != E; ++I) { + CXXMethodDecl *Method = *I; + llvm::StringRef MethodName; + llvm::StringRef MethodLinkageName; + llvm::DIType MethodTy = getOrCreateType(Method->getType(), Unit); + if (CXXConstructorDecl *CDecl = dyn_cast(Method)) { + if (CDecl->isImplicit()) + continue; + MethodName = Decl->getName(); + // FIXME : Find linkage name. + } else if (CXXDestructorDecl *DDecl = dyn_cast(Method)) { + if (DDecl->isImplicit()) + continue; + MethodName = getFunctionName(Method); + // FIXME : Find linkage name. + } else { + // regular method + IdentifierInfo *II = Method->getIdentifier(); + if (!II) + continue; + MethodName = Method->getIdentifier()->getName(); + MethodLinkageName = CGM.getMangledName(Method); + } + + // Get the location for the method. + SourceLocation MethodDefLoc = Method->getLocation(); + PresumedLoc PLoc = SM.getPresumedLoc(MethodDefLoc); + llvm::DICompileUnit MethodDefUnit; + unsigned MethodLine = 0; + + if (!PLoc.isInvalid()) { + MethodDefUnit = getOrCreateCompileUnit(MethodDefLoc); + MethodLine = PLoc.getLine(); + } + + llvm::DISubprogram SP = + DebugFactory.CreateSubprogram(RecordTy , MethodName, MethodName, + MethodLinkageName, + MethodDefUnit, MethodLine, + MethodTy, false, + Method->isThisDeclarationADefinition(), + 0 /*Virtuality*/, 0 /*VIndex*/, + llvm::DIType() /*ContainingType*/); + if (Method->isThisDeclarationADefinition()) + SPCache[cast(Method)] = llvm::WeakVH(SP.getNode()); + EltTys.push_back(SP); + } +} + /// CreateType - get structure or union type. llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, llvm::DICompileUnit Unit) { @@ -568,9 +627,9 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, // Convert all the elements. llvm::SmallVector EltTys; - - CollectRecordFields(Decl, Unit, EltTys); + if (CXXRecordDecl *CXXDecl = dyn_cast(Decl)) + CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl); llvm::DIArray Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size()); @@ -1011,6 +1070,16 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, const Decl *D = GD.getDecl(); if (const FunctionDecl *FD = dyn_cast(D)) { + // If there is a DISubprogram for this function available then use it. + llvm::DenseMap::iterator + FI = SPCache.find(FD); + if (FI != SPCache.end()) { + llvm::DISubprogram SP(dyn_cast_or_null(FI->second)); + if (!SP.isNull() && SP.isSubprogram() && SP.isDefinition()) { + RegionStack.push_back(SP.getNode()); + return; + } + } Name = getFunctionName(FD); if (!Name.empty() && Name[0] == '\01') Name = Name.substr(1); diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 68f92643ab7a..fddd23b4e9c3 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -64,6 +64,8 @@ class CGDebugInfo { /// constructed on demand. For example, C++ destructors, C++ operators etc.. llvm::BumpPtrAllocator FunctionNames; + llvm::DenseMap SPCache; + /// Helper functions for getOrCreateType. llvm::DIType CreateType(const BuiltinType *Ty, llvm::DICompileUnit U); llvm::DIType CreateType(const ComplexType *Ty, llvm::DICompileUnit U); @@ -85,6 +87,10 @@ class CGDebugInfo { llvm::DIType CreatePointerLikeType(unsigned Tag, const Type *Ty, QualType PointeeTy, llvm::DICompileUnit U); + void CollectCXXMemberFunctions(const CXXRecordDecl *Decl, + llvm::DICompileUnit U, + llvm::SmallVectorImpl &E, + llvm::DICompositeType &T); void CollectRecordFields(const RecordDecl *Decl, llvm::DICompileUnit U, llvm::SmallVectorImpl &E); public: