From 9c6c3a0e3ae09626d2d4b04e4ffa42c3d7cab32b Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Thu, 14 Jan 2010 00:36:21 +0000 Subject: [PATCH] Emit human readable names for c/c++ functions. Avoid emitting linkage name if it matches regular name. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93383 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 45 ++++++++++++++++++++++++++++----- lib/CodeGen/CGDebugInfo.h | 13 +++++++++- lib/CodeGen/CodeGenFunction.cpp | 8 +----- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 89f3820d39..8b03ca92af 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -65,6 +65,25 @@ llvm::DIDescriptor CGDebugInfo::getContext(const VarDecl *Decl, return CompileUnit; } +/// getFunctionName - Get function name for the given FunctionDecl. If the +/// name is constructred on demand (e.g. C++ destructor) then the name +/// is stored on the side. +llvm::StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) { + assert (FD && "Invalid FunctionDecl!"); + IdentifierInfo *FII = FD->getIdentifier(); + if (FII) + return FII->getName(); + + // Otherwise construct human readable name for debug info. + std::string NS = FD->getNameAsString(); + + // Copy this name on the side and use its reference. + unsigned Length = NS.length() + 1; + char *StrPtr = FunctionNames.Allocate(Length); + strncpy(StrPtr, NS.c_str(), Length); + return llvm::StringRef(StrPtr); +} + /// getOrCreateCompileUnit - Get the compile unit from the cache or create a new /// one if necessary. This returns null for invalid source locations. llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) { @@ -972,16 +991,28 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, /// EmitFunctionStart - Constructs the debug code for entering a function - /// "llvm.dbg.func.start.". -void CGDebugInfo::EmitFunctionStart(llvm::StringRef Name, QualType FnType, +void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, llvm::Function *Fn, CGBuilderTy &Builder) { - llvm::StringRef LinkageName(Name); - // Skip the asm prefix if it exists. - // - // FIXME: This should probably be the unmangled name? - if (Name[0] == '\01') - Name = Name.substr(1); + llvm::StringRef Name; + llvm::StringRef LinkageName; + + const Decl *D = GD.getDecl(); + if (const FunctionDecl *FD = dyn_cast(D)) { + Name = getFunctionName(FD); + // Use mangled name as linkage name for c/c++ functions. + llvm::StringRef MangledName(CGM.getMangledName(GD)); + if (!Name.equals(MangledName)) + LinkageName = MangledName; + } else { + // Use llvm function name as linkage name. + Name = Fn->getName(); + // Skip the asm prefix if it exists. + if (Name[0] == '\01') + Name = Name.substr(1); + LinkageName = Name; + } // FIXME: Why is this using CurLoc??? llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc); diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 7df2a6247b..8e88988057 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/ValueHandle.h" +#include "llvm/Support/Allocator.h" #include #include "CGBuilder.h" @@ -35,6 +36,7 @@ namespace clang { namespace CodeGen { class CodeGenModule; class CodeGenFunction; + class GlobalDecl; /// CGDebugInfo - This class gathers all debug information during compilation /// and is responsible for emitting to llvm globals or pass directly to @@ -58,6 +60,10 @@ class CGDebugInfo { std::vector > RegionStack; + /// FunctionNames - This is a storage for function names that are + /// constructed on demand. For example, C++ destructors, C++ operators etc.. + llvm::BumpPtrAllocator FunctionNames; + /// Helper functions for getOrCreateType. llvm::DIType CreateType(const BuiltinType *Ty, llvm::DICompileUnit U); llvm::DIType CreateType(const ComplexType *Ty, llvm::DICompileUnit U); @@ -93,7 +99,7 @@ public: /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate /// start of a new function. - void EmitFunctionStart(llvm::StringRef Name, QualType FnType, + void EmitFunctionStart(GlobalDecl GD, QualType FnType, llvm::Function *Fn, CGBuilderTy &Builder); /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start @@ -149,6 +155,11 @@ private: /// CreateTypeNode - Create type metadata for a source language type. llvm::DIType CreateTypeNode(QualType Ty, llvm::DICompileUnit Unit); + + /// getFunctionName - Get function name for the given FunctionDecl. If the + /// name is constructred on demand (e.g. C++ destructor) then the name + /// is stored on the side. + llvm::StringRef getFunctionName(const FunctionDecl *FD); }; } // namespace CodeGen } // namespace clang diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 3592c5ca80..f0a5c64d2f 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -190,15 +190,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0); // Emit subprogram debug descriptor. - // FIXME: The cast here is a huge hack. if (CGDebugInfo *DI = getDebugInfo()) { DI->setLocation(StartLoc); - if (isa(D)) { - DI->EmitFunctionStart(CGM.getMangledName(GD), FnType, CurFn, Builder); - } else { - // Just use LLVM function name. - DI->EmitFunctionStart(Fn->getName(), FnType, CurFn, Builder); - } + DI->EmitFunctionStart(GD, FnType, CurFn, Builder); } // FIXME: Leaked. -- 2.40.0