r312965 - [codeview] omit debug locations for nested exprs unless column info enabled

Bob Haarman via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 11 15:11:57 PDT 2017


Author: inglorion
Date: Mon Sep 11 15:11:57 2017
New Revision: 312965

URL: http://llvm.org/viewvc/llvm-project?rev=312965&view=rev
Log:
[codeview] omit debug locations for nested exprs unless column info enabled

Summary:
Microsoft Visual Studio expects debug locations to correspond to
statements. We used to emit locations for expressions nested inside statements.
This would confuse the debugger, causing it to stop multiple times on the
same line and breaking the "step into specific" feature. This change inhibits
the emission of debug locations for nested expressions when emitting CodeView
debug information, unless column information is enabled.

Fixes PR34312.

Reviewers: rnk, zturner

Reviewed By: rnk

Subscribers: majnemer, echristo, aprantl, cfe-commits

Differential Revision: https://reviews.llvm.org/D37529

Added:
    cfe/trunk/test/CodeGenCXX/debug-info-nested-exprs.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=312965&r1=312964&r2=312965&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Sep 11 15:11:57 2017
@@ -97,6 +97,10 @@ void ApplyDebugLocation::init(SourceLoca
   }
 
   OriginalLocation = CGF->Builder.getCurrentDebugLocation();
+
+  if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
+    return;
+
   if (TemporaryLocation.isValid()) {
     DI->EmitLocation(CGF->Builder, TemporaryLocation);
     return;

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=312965&r1=312964&r2=312965&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Sep 11 15:11:57 2017
@@ -3553,6 +3553,10 @@ CodeGenModule::GetAddrOfConstantCFString
   return ConstantAddress(GV, Alignment);
 }
 
+bool CodeGenModule::getExpressionLocationsEnabled() const {
+  return !CodeGenOpts.EmitCodeView || CodeGenOpts.DebugColumnInfo;
+}
+
 QualType CodeGenModule::getObjCFastEnumerationStateType() {
   if (ObjCFastEnumerationStateType.isNull()) {
     RecordDecl *D = Context.buildImplicitRecord("__objcFastEnumerationState");

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=312965&r1=312964&r2=312965&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Sep 11 15:11:57 2017
@@ -513,6 +513,9 @@ public:
   /// Finalize LLVM code generation.
   void Release();
 
+  /// Return true if we should emit location information for expressions.
+  bool getExpressionLocationsEnabled() const;
+
   /// Return a reference to the configured Objective-C runtime.
   CGObjCRuntime &getObjCRuntime() {
     if (!ObjCRuntime) createObjCRuntime();

Added: cfe/trunk/test/CodeGenCXX/debug-info-nested-exprs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-nested-exprs.cpp?rev=312965&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-nested-exprs.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-info-nested-exprs.cpp Mon Sep 11 15:11:57 2017
@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN:    -std=c++11 -gcodeview -emit-llvm -o - %s \
+// RUN:    | FileCheck -check-prefix=NONEST %s
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN:    -std=c++11 -gcodeview -dwarf-column-info -emit-llvm -o - %s \
+// RUN:    | FileCheck -check-prefix=COLUMNS %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN:    -std=c++11 -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN:    -std=c++11 -dwarf-column-info -emit-llvm -o - %s \
+// RUN:    | FileCheck -check-prefix=COLUMNS %s
+
+class Foo {
+public:
+  static Foo create();
+  void func();
+  int *begin();
+  int *end();
+};
+
+int bar(int x, int y);
+int baz(int x, int y);
+int qux(int x, int y);
+int onearg(int x);
+int noargs();
+int noargs1();
+Foo range(int x);
+
+int foo(int x, int y, int z) {
+  int a = bar(x, y) +
+          baz(x, z) +
+          qux(y, z);
+  // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[LOC:[0-9]+]]
+  // NONEST: call i32 @{{.*}}baz{{.*}}, !dbg ![[LOC]]
+  // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[LOC]]
+  // NONEST: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[LOC]]
+  // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+  // NESTED: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+  // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+  // NESTED: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[BAR]]
+  // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+  // COLUMNS: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[DECLA:[0-9]+]]
+
+  int i = 1, b = 0, c = 0;
+  // NONEST: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+  // NONEST: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+  // NONEST: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+  // NESTED: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+  // NESTED: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+  // NESTED: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+  // COLUMNS: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+  // COLUMNS: store i32 0, i32* %b,{{.*}} !dbg ![[BLOC:[0-9]+]]
+  // COLUMNS: store i32 0, i32* %c,{{.*}} !dbg ![[CLOC:[0-9]+]]
+
+  while (i > 0) {
+    b = bar(a, b);
+    --i;
+  }
+  // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+  // NONEST: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+  // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+  // NESTED: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+  // COLUMNS: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+
+  for (i = 0; i < 1; i++) {
+    b = bar(a, b);
+    c = qux(a, c);
+  }
+  // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+  // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+  // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+  // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+
+  if (a < b) {
+    int t = a;
+    a = b;
+    b = t;
+  }
+  // NONEST: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+  // NONEST: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+  // NONEST: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+  // NESTED: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+  // NESTED: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+  // NESTED: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+  // COLUMNS: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+  // COLUMNS: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+  // COLUMNS: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+
+  int d = onearg(
+      noargs());
+  // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DECLD:[0-9]+]]
+  // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD]]
+  // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+  // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+  // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD:[0-9]+]]
+  // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+  // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DONEARG:[0-9]+]]
+  // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD:[0-9]+]]
+  
+  d = onearg(noargs());
+  // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+  // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+  // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+  // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+  // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+  // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+  // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETDNOARGS:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETDONEARG:[0-9]+]]
+  // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD:[0-9]+]]
+
+  for (const auto x : range(noargs())) noargs1();
+  // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+  // NONEST: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+  // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+  // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+  // NESTED: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+  // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR_NOARGS:[0-9]+]]
+  // COLUMNS: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR_RANGE:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+
+  if (noargs() && noargs1()) {
+    Foo::create().func();
+  }
+  // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+  // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+  // NONEST: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+  // NONEST: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+  // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+  // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+  // NESTED: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+  // NESTED: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+  // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[ANDLHS:[0-9]+]]
+  // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[ANDRHS:[0-9]+]]
+  // COLUMNS: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_CREATE:[0-9]+]]
+  // COLUMNS: call void @{{.*}}func{{.*}}, !dbg ![[AND_FUNC:[0-9]+]]
+
+  return a -
+         (b * z);
+  // NONEST: mul nsw i32 {{.*}}, !dbg ![[RETLOC:[0-9]+]]
+  // NONEST: sub nsw i32 {{.*}}, !dbg ![[RETLOC]]
+  // NONEST: ret i32 {{.*}}, !dbg ![[RETLOC]]
+  // NESTED: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+  // NESTED: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+  // NESTED: ret i32 {{.*}}, !dbg !
+  // COLUMNS: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+  // COLUMNS: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+  // COLUMNS: ret i32 {{.*}}, !dbg !
+}
+
+// NONEST: ![[WHILE1]] = !DILocation(
+// NONEST: ![[WHILE2]] = !DILocation(
+// NONEST: ![[FOR1]] = !DILocation(
+// NONEST: ![[FOR2]] = !DILocation(
+// NONEST: ![[IF1]] = !DILocation(
+// NONEST: ![[IF2]] = !DILocation(
+// NONEST: ![[IF3]] = !DILocation(
+// NONEST: ![[RANGEFOR]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NONEST: ![[RANGEFOR_BODY]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE]]
+
+// NESTED: ![[BAR]] = !DILocation(
+// NESTED: ![[BAZ]] = !DILocation(
+// NESTED: ![[QUX]] = !DILocation(
+// NESTED: ![[DECLD]] = !DILocation
+// NESTED: ![[DNOARGS]] = !DILocation
+// NESTED: ![[RANGEFOR]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NESTED: ![[RANGEFOR_BODY]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE]]
+// NESTED: ![[RETSUB]] = !DILocation(
+// NESTED: ![[RETMUL]] = !DILocation(
+
+// COLUMNS: ![[DECLA]] = !DILocation(
+// COLUMNS: ![[BAR]] = !DILocation(
+// COLUMNS: ![[BAZ]] = !DILocation(
+// COLUMNS: ![[QUX]] = !DILocation(
+// COLUMNS: ![[ILOC]] = !DILocation(
+// COLUMNS: ![[BLOC]] = !DILocation(
+// COLUMNS: ![[CLOC]] = !DILocation(
+// COLUMNS: ![[DECLD]] = !DILocation(
+// COLUMNS: ![[DNOARGS]] = !DILocation(
+// COLUMNS: ![[DONEARG]] = !DILocation(
+// COLUMNS: ![[SETDNOARGS]] = !DILocation(
+// COLUMNS: ![[SETDONEARG]] = !DILocation(
+// COLUMNS: ![[SETD]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_NOARGS]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_RANGE]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_BODY]] = !DILocation(
+// COLUMNS: ![[ANDLHS]] = !DILocation
+// COLUMNS: ![[ANDRHS]] = !DILocation
+// COLUMNS: ![[AND_CREATE]] = !DILocation
+// COLUMNS: ![[AND_FUNC]] = !DILocation
+// COLUNMS: ![[RETSUB]] = !DILocation(
+// COLUMNS: ![[RETMUL]] = !DILocation(




More information about the cfe-commits mailing list