diff options
author | Adrian Prantl <aprantl@apple.com> | 2013-03-12 20:43:25 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2013-03-12 20:43:25 +0000 |
commit | 00df5eaa9f4f7cc0809fd47c95311b532fbe63c6 (patch) | |
tree | 3ce8a9297a558a5beff173208e25661fa3abe03e | |
parent | 61d16c1f491f5ad6d4a254dcca8868acb5f150cc (diff) |
Force column info to be generated for call expressions so we can
differentiate multiple inlined call sites on the same line
in the debug info.
Fixes rdar://problem/13036237
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176895 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 8 | ||||
-rw-r--r-- | test/CodeGenCXX/debug-info-same-line.cpp | 66 |
4 files changed, 90 insertions, 15 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index a139597c26..4aed943689 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -262,9 +262,9 @@ unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) { } /// getColumnNumber - Get column number for the location. -unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc) { +unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) { // We may not want column information at all. - if (!CGM.getCodeGenOpts().DebugColumnInfo) + if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo) return 0; // If the location is invalid then use the current column. @@ -1872,9 +1872,9 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { TC = llvm::DIType(cast<llvm::MDNode>(it->second.first)); else TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, - Decl->getName(), TheCU, Unit, - getLineNumber(Decl->getLocation()), - TheCU.getLanguage()); + Decl->getName(), TheCU, Unit, + getLineNumber(Decl->getLocation()), + TheCU.getLanguage()); // Store the forward declaration in the cache. ObjCInterfaceCache[TyPtr] = std::make_pair(TC, Checksum(Decl)); @@ -1891,7 +1891,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { /// Currently the checksum merely consists of the number of ivars. unsigned CGDebugInfo::Checksum(const ObjCInterfaceDecl - *InterfaceDecl) { + *InterfaceDecl) { unsigned IvarNo = 0; for (const ObjCIvarDecl *Ivar = InterfaceDecl->all_declared_ivar_begin(); Ivar != 0; Ivar = Ivar->getNextIvar()) ++IvarNo; @@ -2055,7 +2055,7 @@ llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) { llvm::DIArray()); } else RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line, - Size, Align, 0, llvm::DIType(), llvm::DIArray()); + Size, Align, 0, llvm::DIType(), llvm::DIArray()); RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl); TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = llvm::DIType(RealDecl); @@ -2291,7 +2291,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, /// EmitLocation - Emit metadata to indicate a change in line/column /// information in the source file. -void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) { +void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc, + bool ForceColumnInfo) { // Update our current location setLocation(Loc); @@ -2312,9 +2313,10 @@ void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) { PrevLoc = CurLoc; llvm::MDNode *Scope = LexicalBlockStack.back(); - Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(CurLoc), - getColumnNumber(CurLoc), - Scope)); + Builder.SetCurrentDebugLocation(llvm::DebugLoc::get + (getLineNumber(CurLoc), + getColumnNumber(CurLoc, ForceColumnInfo), + Scope)); } /// CreateLexicalBlock - Creates a new lexical block node and pushes it on diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 2e896cfe22..73dd15317e 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -207,7 +207,9 @@ public: /// EmitLocation - Emit metadata to indicate a change in line/column /// information in the source file. - void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc); + /// \param ForceColumnInfo Assume DebugColumnInfo option is true. + void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc, + bool ForceColumnInfo = false); /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate /// start of a new function. @@ -356,7 +358,8 @@ private: /// getColumnNumber - Get column number for the location. If location is /// invalid then use current location. - unsigned getColumnNumber(SourceLocation Loc); + /// \param Force Assume DebugColumnInfo option is true. + unsigned getColumnNumber(SourceLocation Loc, bool Force=false); }; } // namespace CodeGen } // namespace clang diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 830b1218c1..5e6342ae38 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2849,8 +2849,12 @@ RValue CodeGenFunction::EmitRValueForField(LValue LV, RValue CodeGenFunction::EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue) { - if (CGDebugInfo *DI = getDebugInfo()) - DI->EmitLocation(Builder, E->getLocStart()); + if (CGDebugInfo *DI = getDebugInfo()) { + SourceLocation Loc = E->getLocStart(); + DI->EmitLocation(Builder, Loc, + /* Force column info to be generated so we can differentiate + multiple call sites on the same line in the debug info. */ true); + } // Builtins never have block type. if (E->getCallee()->getType()->isBlockPointerType()) diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp new file mode 100644 index 0000000000..6658c883db --- /dev/null +++ b/test/CodeGenCXX/debug-info-same-line.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -g -emit-obj -o %t %s +// RUN: llvm-dwarfdump %t | FileCheck %s +// In the attached test case a post-r166236 clang coalesces two +// instances of an inlined function in a way that makes it appear as +// if the function was only inlined once. + +#define INLINE inline __attribute__((always_inline)) + +INLINE int +product (int x, int y) +{ + int result = x * y; + return result; +} + +INLINE int +sum (int a, int b) +{ + int result = a + b; + return result; +} + +int +strange_max (int m, int n) +{ + if (m > n) + return m; + else if (n > m) + return n; + else + return 0; +} + +int +foo (int i, int j) +{ + if (strange_max (i, j) == i) + return product (i, j); + else if (strange_max (i, j) == j) + return sum (i, j); + else + return product (sum (i, i), sum (j, j)); +} + +int +main(int argc, char const *argv[]) +{ + + int array[3]; + + array[0] = foo (1238, 78392); + array[1] = foo (379265, 23674); + array[2] = foo (872934, 234); + + return 0; +} + +// CHECK: DW_TAG_inlined_subroutine +// CHECK: DW_TAG_inlined_subroutine +// CHECK: DW_TAG_inlined_subroutine +// CHECK: DW_TAG_inlined_subroutine +// CHECK-NOT: DW_TAG_inlined_subroutine +// CHECK: DW_AT_call_line {{.*}} (0x2a) +// CHECK: DW_TAG_inlined_subroutine +// CHECK-NOT: DW_TAG_inlined_subroutine +// CHECK: DW_AT_call_line {{.*}} (0x2a) |