aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2013-03-12 20:43:25 +0000
committerAdrian Prantl <aprantl@apple.com>2013-03-12 20:43:25 +0000
commit00df5eaa9f4f7cc0809fd47c95311b532fbe63c6 (patch)
tree3ce8a9297a558a5beff173208e25661fa3abe03e
parent61d16c1f491f5ad6d4a254dcca8868acb5f150cc (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.cpp24
-rw-r--r--lib/CodeGen/CGDebugInfo.h7
-rw-r--r--lib/CodeGen/CGExpr.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-same-line.cpp66
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)