diff options
author | Bob Haarman <llvm@inglorion.net> | 2017-09-11 22:11:57 +0000 |
---|---|---|
committer | Bob Haarman <llvm@inglorion.net> | 2017-09-11 22:11:57 +0000 |
commit | c6c9b8fa1fbfcda3dbcb6be2d085f8b4d69d44d1 (patch) | |
tree | 3c47e1d359b4d95145e7ed21da79c5998b8a8e5e | |
parent | d2da71f971c92d0d1f257ccc80d7daf4de14adf5 (diff) | |
download | bcm5719-llvm-c6c9b8fa1fbfcda3dbcb6be2d085f8b4d69d44d1.tar.gz bcm5719-llvm-c6c9b8fa1fbfcda3dbcb6be2d085f8b4d69d44d1.zip |
[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
llvm-svn: 312965
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/debug-info-nested-exprs.cpp | 202 |
4 files changed, 213 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index befb704f39e..f4c84c5c630 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -97,6 +97,10 @@ void ApplyDebugLocation::init(SourceLocation TemporaryLocation, } OriginalLocation = CGF->Builder.getCurrentDebugLocation(); + + if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled()) + return; + if (TemporaryLocation.isValid()) { DI->EmitLocation(CGF->Builder, TemporaryLocation); return; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index b0b5e7d387f..43607002544 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3553,6 +3553,10 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { return ConstantAddress(GV, Alignment); } +bool CodeGenModule::getExpressionLocationsEnabled() const { + return !CodeGenOpts.EmitCodeView || CodeGenOpts.DebugColumnInfo; +} + QualType CodeGenModule::getObjCFastEnumerationStateType() { if (ObjCFastEnumerationStateType.isNull()) { RecordDecl *D = Context.buildImplicitRecord("__objcFastEnumerationState"); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 235ef31bd7a..4bff296cb19 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -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(); diff --git a/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp b/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp new file mode 100644 index 00000000000..bd70373e228 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp @@ -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( |