Index: include/clang/Sema/Scope.h =================================================================== --- include/clang/Sema/Scope.h +++ include/clang/Sema/Scope.h @@ -259,6 +259,9 @@ Scope *getTemplateParamParent() { return TemplateParamParent; } const Scope *getTemplateParamParent() const { return TemplateParamParent; } + /// Returns the depth of this scope. The translation-unit has scope depth 0. + unsigned getDepth() const { return Depth; } + /// Returns the number of function prototype scopes in this scope /// chain. unsigned getFunctionPrototypeDepth() const { Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -2025,7 +2025,7 @@ /// Build a variable declaration for a for-range statement. VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc, - QualType Type, const char *Name) { + QualType Type, StringRef Name) { DeclContext *DC = SemaRef.CurContext; IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); @@ -2094,10 +2094,12 @@ } // Build auto && __range = range-init + // Assume the variables are nested in the inner scope (loop body). + const auto DepthStr = std::to_string(S->getDepth() >> 1); SourceLocation RangeLoc = Range->getLocStart(); VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc, Context.getAutoRRefDeductType(), - "__range"); + std::string("__range") + DepthStr); if (FinishForRangeVarDecl(*this, RangeVar, Range, RangeLoc, diag::err_for_range_deduction_failure)) { LoopVar->setInvalidDecl(); @@ -2340,10 +2342,12 @@ return StmtError(); // Build auto __begin = begin-expr, __end = end-expr. + // Assume the variables are nested in the inner scope (loop body). + const auto DepthStr = std::to_string(S->getDepth() >> 1); VarDecl *BeginVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType, - "__begin"); + std::string("__begin") + DepthStr); VarDecl *EndVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType, - "__end"); + std::string("__end") + DepthStr); // Build begin-expr and end-expr and attach to __begin and __end variables. ExprResult BeginExpr, EndExpr; Index: test/CodeGenCXX/debug-for-range-scope-hints.cpp =================================================================== --- test/CodeGenCXX/debug-for-range-scope-hints.cpp +++ test/CodeGenCXX/debug-for-range-scope-hints.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +struct vec { + using itr = int*; + itr begin() { return nullptr; } + itr end() { return nullptr; } +}; + +void test() { + vec as, bs, cs; + + for (auto a : as) + for (auto b : bs) + for (auto c : cs) { + } +} + +// CHECK: define void @_Z4testv() +// CHECK: call void @llvm.dbg.declare(metadata %struct.vec** {{.*}}, metadata ![[RANGE1:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[BEGIN1:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[END1:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata %struct.vec** {{.*}}, metadata ![[RANGE2:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[BEGIN2:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[END2:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata %struct.vec** {{.*}}, metadata ![[RANGE3:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[BEGIN3:[0-9]+]] +// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[END3:[0-9]+]] +// CHECK: ![[RANGE1]] = !DILocalVariable(name: "__range1", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[BEGIN1]] = !DILocalVariable(name: "__begin1", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[END1]] = !DILocalVariable(name: "__end1", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[RANGE2]] = !DILocalVariable(name: "__range2", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[BEGIN2]] = !DILocalVariable(name: "__begin2", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[END2]] = !DILocalVariable(name: "__end2", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[RANGE3]] = !DILocalVariable(name: "__range3", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[BEGIN3]] = !DILocalVariable(name: "__begin3", {{.*}}, flags: DIFlagArtificial) +// CHECK: ![[END3]] = !DILocalVariable(name: "__end3", {{.*}}, flags: DIFlagArtificial) Index: test/CodeGenCXX/debug-info-scope.cpp =================================================================== --- test/CodeGenCXX/debug-info-scope.cpp +++ test/CodeGenCXX/debug-info-scope.cpp @@ -58,7 +58,7 @@ } int x[] = {1, 2}; - // CHECK: = !DILocalVariable(name: "__range" + // CHECK: = !DILocalVariable(name: "__range1" // CHECK-SAME: scope: [[RANGE_FOR:![0-9]*]] // CHECK-NOT: line: // CHECK-SAME: ){{$}} Index: test/CodeGenCXX/vla.cpp =================================================================== --- test/CodeGenCXX/vla.cpp +++ test/CodeGenCXX/vla.cpp @@ -68,8 +68,8 @@ void test2(int b) { // CHECK-LABEL: define void {{.*}}test2{{.*}}(i32 %b) int varr[b]; - // AMD: %__end = alloca i32*, align 8, addrspace(5) - // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end to i32** + // AMD: %__end1 = alloca i32*, align 8, addrspace(5) + // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end1 to i32** // get the address of %b by checking the first store that stores it //CHECK: store i32 %b, i32* [[PTR_B:%.*]] @@ -86,7 +86,7 @@ //CHECK: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_NUM_ELEMENTS_PRE]] //CHECK-NEXT: [[VLA_NUM_ELEMENTS_POST:%.*]] = udiv i64 [[VLA_SIZEOF]], 4 //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]] - //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end + //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end1 //AMD-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]] for (int d : varr) 0; } @@ -94,8 +94,8 @@ void test3(int b, int c) { // CHECK-LABEL: define void {{.*}}test3{{.*}}(i32 %b, i32 %c) int varr[b][c]; - // AMD: %__end = alloca i32*, align 8, addrspace(5) - // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end to i32** + // AMD: %__end1 = alloca i32*, align 8, addrspace(5) + // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end1 to i32** // get the address of %b by checking the first store that stores it //CHECK: store i32 %b, i32* [[PTR_B:%.*]] //CHECK-NEXT: store i32 %c, i32* [[PTR_C:%.*]]