diff options
author | Devang Patel <dpatel@apple.com> | 2011-04-23 00:08:01 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2011-04-23 00:08:01 +0000 |
commit | 120bf32525829be4622fc85b67e38b2ff0276744 (patch) | |
tree | f536cdc71166b8f149e18fb1a0605cd2cbdf43c0 | |
parent | bb29d1ba8b0895e3923c724f49845636f35b4bde (diff) |
Tie debug information for method declaration with debug information for method definition.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130037 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 31 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 4 | ||||
-rw-r--r-- | test/CodeGenCXX/debug-info-method-spec.cpp | 10 |
3 files changed, 42 insertions, 3 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index aa664491fc..492429ed9a 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -764,7 +764,7 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, // Don't cache ctors or dtors since we have to emit multiple functions for // a single ctor or dtor. - if (!IsCtorOrDtor && Method->isThisDeclarationADefinition()) + if (!IsCtorOrDtor) SPCache[Method] = llvm::WeakVH(SP); return SP; @@ -1579,6 +1579,29 @@ llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType, return Ty; } +/// getFunctionDeclaration - Return debug info descriptor to describe method +/// declaration for the given method definition. +llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { + const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); + if (!FD) return llvm::DISubprogram(); + + // Setup context. + getContextDescriptor(cast<Decl>(D->getDeclContext())); + + for (FunctionDecl::redecl_iterator I = FD->redecls_begin(), + E = FD->redecls_end(); I != E; ++I) { + const FunctionDecl *NextFD = *I; + llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator + MI = SPCache.find(NextFD); + if (MI != SPCache.end()) { + llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(&*MI->second)); + if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition()) + return SP; + } + } + return llvm::DISubprogram(); +} + /// EmitFunctionStart - Constructs the debug code for entering a function - /// "llvm.dbg.func.start.". void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, @@ -1639,12 +1662,14 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, unsigned LineNo = getLineNumber(CurLoc); if (D->isImplicit()) Flags |= llvm::DIDescriptor::FlagArtificial; + llvm::DIType SPTy = getOrCreateType(FnType, Unit); + llvm::DISubprogram SPDecl = getFunctionDeclaration(D); llvm::DISubprogram SP = DBuilder.createFunction(FDContext, Name, LinkageName, Unit, - LineNo, getOrCreateType(FnType, Unit), + LineNo, SPTy, Fn->hasInternalLinkage(), true/*definition*/, Flags, CGM.getLangOptions().Optimize, Fn, - TParamsArray); + TParamsArray, SPDecl); // Push function on region stack. llvm::MDNode *SPN = SP; diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index f806f630b9..af00c2f84f 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -258,6 +258,10 @@ private: llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType, llvm::StringRef Name, uint64_t *Offset); + /// getFunctionDeclaration - Return debug info descriptor to describe method + /// declaration for the given method definition. + llvm::DISubprogram getFunctionDeclaration(const Decl *D); + /// 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. diff --git a/test/CodeGenCXX/debug-info-method-spec.cpp b/test/CodeGenCXX/debug-info-method-spec.cpp new file mode 100644 index 0000000000..31f66633dc --- /dev/null +++ b/test/CodeGenCXX/debug-info-method-spec.cpp @@ -0,0 +1,10 @@ +// RUN: %clang -fverbose-asm -cc1 -g -S %s -o - | grep DW_AT_specification +// Radar 9254491 +class A { +public: + void doSomething(int i) { ++i; } +}; + +void foo(A *a) { + a->doSomething(2); +} |