Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -97,6 +97,10 @@ } OriginalLocation = CGF->Builder.getCurrentDebugLocation(); + + if (!DI->CGM.getNestedExpressionLocationsEnabled()) + return; + if (TemporaryLocation.isValid()) { DI->EmitLocation(CGF->Builder, TemporaryLocation); return; Index: clang/lib/CodeGen/CodeGenModule.h =================================================================== --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -29,6 +29,7 @@ #include "clang/Basic/Module.h" #include "clang/Basic/SanitizerBlacklist.h" #include "clang/Basic/XRayLists.h" +#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -70,7 +71,6 @@ class ValueDecl; class VarDecl; class LangOptions; -class CodeGenOptions; class HeaderSearchOptions; class PreprocessorOptions; class DiagnosticsEngine; @@ -513,6 +513,11 @@ /// Finalize LLVM code generation. void Release(); + /// Return true if we should emit location information for nested expressions. + bool getNestedExpressionLocationsEnabled() const { + return !CodeGenOpts.EmitCodeView || CodeGenOpts.DebugColumnInfo; + } + /// Return a reference to the configured Objective-C runtime. CGObjCRuntime &getObjCRuntime() { if (!ObjCRuntime) createObjCRuntime(); Index: clang/test/CodeGenCXX/debug-info-nested-exprs.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-nested-exprs.cpp @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \ +// RUN: -gcodeview -emit-llvm -o - %s | FileCheck -check-prefix=NONEST %s +// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \ +// RUN: -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: -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s +// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \ +// RUN: -dwarf-column-info -emit-llvm -o - %s \ +// RUN: | FileCheck -check-prefix=COLUMNS %s + +// NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[LOC:[0-9]+]] +// NONEST: call i32 @{{.*}}baz{{.*}}, !dbg ![[LOC]] +// NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[LOC]] +// NONEST: store i32 {{.*}}, !dbg ![[LOC]] +// 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]] +// NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]] +// NONEST: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]] +// NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]] +// NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]] +// 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]+]] +// NONEST: mul nsw i32 {{.*}}, !dbg ![[RETLOC:[0-9]+]] +// NONEST: sub nsw i32 {{.*}}, !dbg ![[RETLOC]] +// NONEST: ret i32 {{.*}}, !dbg ![[RETLOC]] +// NONEST: ![[WHILE1]] = !DILocation( +// NONEST: ![[WHILE2]] = !DILocation( +// NONEST: ![[FOR1]] = !DILocation( +// NONEST: ![[FOR2]] = !DILocation( +// NONEST: ![[IF1]] = !DILocation( +// NONEST: ![[IF2]] = !DILocation( +// NONEST: ![[IF3]] = !DILocation( + +// 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 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]] +// NESTED: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]] +// NESTED: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]] +// NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]] +// NESTED: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]] +// NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]] +// NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[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]+]] +// NESTED: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]] +// NESTED: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]] +// NESTED: ret i32 {{.*}}, !dbg ! +// NESTED: ![[BAR]] = !DILocation( +// NESTED: ![[BAZ]] = !DILocation( +// NESTED: ![[QUX]] = !DILocation( +// NESTED: ![[RETSUB]] = !DILocation( +// NESTED: ![[RETMUL]] = !DILocation( + +// 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 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]+]] +// COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]] +// COLUMNS: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]] +// COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]] +// COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[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]+]] +// COLUMNS: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]] +// COLUMNS: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]] +// COLUMNS: ret i32 {{.*}}, !dbg ! +// COLUMNS: ![[BAR]] = !DILocation( +// COLUMNS: ![[BAZ]] = !DILocation( +// COLUMNS: ![[QUX]] = !DILocation( +// COLUMNS: ![[ILOC]] = !DILocation( +// COLUMNS: ![[BLOC]] = !DILocation( +// COLUMNS: ![[CLOC]] = !DILocation( +// COLUNMS: ![[RETSUB]] = !DILocation( +// COLUMNS: ![[RETMUL]] = !DILocation( + +int bar(int x, int y); +int baz(int x, int y); +int qux(int x, int y); + +int foo(int x, int y, int z) { + int a = bar(x, y) + + baz(x, z) + + qux(y, z); + + int i = 1, b = 0, c = 0; + while (i > 0) { + b = bar(a, b); + --i; + } + for (i = 0; i < 1; i++) { + b = bar(a, b); + c = qux(a, c); + } + if (a < b) { + int t = a; + a = b; + b = t; + } + + return a - + (b * z); +}