Index: cfe/trunk/lib/CodeGen/CGDebugInfo.h =================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.h +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h @@ -320,6 +320,9 @@ /// ignored. void setLocation(SourceLocation Loc); + // Converts a SourceLocation to a DebugLoc + llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc); + /// Emit metadata to indicate a change in line/column information in /// the source file. If the location is invalid, the previous /// location will be reused. Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp @@ -3924,3 +3924,12 @@ // Don't ignore in case of explicit cast where it is referenced indirectly. DBuilder.retainType(DieTy); } + +llvm::DebugLoc CGDebugInfo::SourceLocToDebugLoc(SourceLocation Loc) { + if (LexicalBlockStack.empty()) + return llvm::DebugLoc(); + + llvm::MDNode *Scope = LexicalBlockStack.back(); + return llvm::DebugLoc::get( + getLineNumber(Loc), getColumnNumber(Loc), Scope); +} Index: cfe/trunk/lib/CodeGen/CGLoopInfo.h =================================================================== --- cfe/trunk/lib/CodeGen/CGLoopInfo.h +++ cfe/trunk/lib/CodeGen/CGLoopInfo.h @@ -67,7 +67,7 @@ public: /// \brief Construct a new LoopInfo for the loop with entry Header. LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, - llvm::DebugLoc Location); + llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc); /// \brief Get the loop id metadata for this loop. llvm::MDNode *getLoopID() const { return LoopID; } @@ -99,14 +99,14 @@ /// \brief Begin a new structured loop. The set of staged attributes will be /// applied to the loop and then cleared. - void push(llvm::BasicBlock *Header, - llvm::DebugLoc Location = llvm::DebugLoc()); + void push(llvm::BasicBlock *Header, llvm::DebugLoc StartLoc, + llvm::DebugLoc EndLoc); /// \brief Begin a new structured loop. Stage attributes from the Attrs list. /// The staged attributes are applied to the loop and then cleared. void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx, - llvm::ArrayRef Attrs, - llvm::DebugLoc Location = llvm::DebugLoc()); + llvm::ArrayRef Attrs, llvm::DebugLoc StartLoc, + llvm::DebugLoc EndLoc); /// \brief End the current loop. void pop(); Index: cfe/trunk/lib/CodeGen/CGLoopInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGLoopInfo.cpp +++ cfe/trunk/lib/CodeGen/CGLoopInfo.cpp @@ -20,14 +20,14 @@ using namespace llvm; static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, - llvm::DebugLoc Location) { + llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc) { if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 && Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 && Attrs.VectorizeEnable == LoopAttributes::Unspecified && Attrs.UnrollEnable == LoopAttributes::Unspecified && Attrs.DistributeEnable == LoopAttributes::Unspecified && - !Location) + !StartLoc && !EndLoc) return nullptr; SmallVector Args; @@ -35,9 +35,14 @@ auto TempNode = MDNode::getTemporary(Ctx, None); Args.push_back(TempNode.get()); - // If we have a valid debug location for the loop, add it. - if (Location) - Args.push_back(Location.getAsMDNode()); + // If we have a valid start debug location for the loop, add it. + if (StartLoc) { + Args.push_back(StartLoc.getAsMDNode()); + + // If we also have a valid end debug location for the loop, add it. + if (EndLoc) + Args.push_back(EndLoc.getAsMDNode()); + } // Setting vectorize.width if (Attrs.VectorizeWidth > 0) { @@ -116,20 +121,21 @@ } LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, - llvm::DebugLoc Location) + llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc) : LoopID(nullptr), Header(Header), Attrs(Attrs) { - LoopID = createMetadata(Header->getContext(), Attrs, Location); + LoopID = createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc); } -void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc Location) { - Active.push_back(LoopInfo(Header, StagedAttrs, Location)); +void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc StartLoc, + llvm::DebugLoc EndLoc) { + Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc)); // Clear the attributes so nested loops do not inherit them. StagedAttrs.clear(); } void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, ArrayRef Attrs, - llvm::DebugLoc Location) { + llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc) { // Identify loop hint attributes from Attrs. for (const auto *Attr : Attrs) { @@ -267,7 +273,7 @@ } /// Stage the attributes. - push(Header, Location); + push(Header, StartLoc, EndLoc); } void LoopInfoStack::pop() { Index: cfe/trunk/lib/CodeGen/CGStmt.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGStmt.cpp +++ cfe/trunk/lib/CodeGen/CGStmt.cpp @@ -663,8 +663,10 @@ JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); EmitBlock(LoopHeader.getBlock()); + const SourceRange &R = S.getSourceRange(); LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs, - Builder.getCurrentDebugLocation()); + SourceLocToDebugLoc(R.getBegin()), + SourceLocToDebugLoc(R.getEnd())); // Create an exit block for when the condition fails, which will // also become the break target. @@ -755,8 +757,10 @@ // Emit the body of the loop. llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); + const SourceRange &R = S.getSourceRange(); LoopStack.push(LoopBody, CGM.getContext(), DoAttrs, - Builder.getCurrentDebugLocation()); + SourceLocToDebugLoc(R.getBegin()), + SourceLocToDebugLoc(R.getEnd())); EmitBlockWithFallThrough(LoopBody, &S); { @@ -808,8 +812,6 @@ LexicalScope ForScope(*this, S.getSourceRange()); - llvm::DebugLoc DL = Builder.getCurrentDebugLocation(); - // Evaluate the first part before the loop. if (S.getInit()) EmitStmt(S.getInit()); @@ -821,7 +823,10 @@ llvm::BasicBlock *CondBlock = Continue.getBlock(); EmitBlock(CondBlock); - LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL); + const SourceRange &R = S.getSourceRange(); + LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, + SourceLocToDebugLoc(R.getBegin()), + SourceLocToDebugLoc(R.getEnd())); // If the for loop doesn't have an increment we can just use the // condition as the continue block. Otherwise we'll need to create @@ -906,8 +911,6 @@ LexicalScope ForScope(*this, S.getSourceRange()); - llvm::DebugLoc DL = Builder.getCurrentDebugLocation(); - // Evaluate the first pieces before the loop. EmitStmt(S.getRangeStmt()); EmitStmt(S.getBeginStmt()); @@ -919,7 +922,10 @@ llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL); + const SourceRange &R = S.getSourceRange(); + LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, + SourceLocToDebugLoc(R.getBegin()), + SourceLocToDebugLoc(R.getEnd())); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. Index: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp @@ -1304,7 +1304,9 @@ // Start the loop with a block that tests the condition. auto CondBlock = createBasicBlock("omp.inner.for.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock, Builder.getCurrentDebugLocation()); + const SourceRange &R = S.getSourceRange(); + LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()), + SourceLocToDebugLoc(R.getEnd())); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. @@ -1705,7 +1707,9 @@ // Start the loop with a block that tests the condition. auto CondBlock = createBasicBlock("omp.dispatch.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock, Builder.getCurrentDebugLocation()); + const SourceRange &R = S.getSourceRange(); + LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()), + SourceLocToDebugLoc(R.getEnd())); llvm::Value *BoolCondVal = nullptr; if (!DynamicOrOrdered) { Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -2113,6 +2113,10 @@ OffsetValue); } + /// Converts Location to a DebugLoc, if debug information is enabled. + llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location); + + //===--------------------------------------------------------------------===// // Declaration Emission //===--------------------------------------------------------------------===// Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp @@ -2080,3 +2080,10 @@ IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation()); CGM.getSanStats().create(IRB, SSK); } + +llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) { + if (CGDebugInfo *DI = getDebugInfo()) + return DI->SourceLocToDebugLoc(Location); + + return llvm::DebugLoc(); +} Index: cfe/trunk/test/CodeGenCXX/debug-info-line-if.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/debug-info-line-if.cpp +++ cfe/trunk/test/CodeGenCXX/debug-info-line-if.cpp @@ -53,15 +53,19 @@ // CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}}) // CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}}) - // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[LDBG1:![0-9]*]]} - // CHECK-DAG: [[LDBG1]] = !DILocation(line: 100, scope: !{{.*}}) - - // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]} - // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}}) - - // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]} - // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}}) - - // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]} - // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}}) + // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]} + // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}}) + + // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]} + // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}}) + + // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]} + // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}}) + + // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]} + // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 401, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 405, scope: !{{.*}}) } Index: cfe/trunk/test/CodeGenCXX/debug-info-loops.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/debug-info-loops.cpp +++ cfe/trunk/test/CodeGenCXX/debug-info-loops.cpp @@ -0,0 +1,49 @@ +// RUN: %clang -g -gcolumn-info -std=c++11 -S -emit-llvm %s -o - | FileCheck %s +extern int v[2]; +int a = 0, b = 0; +int main() { +#line 100 + for (int x : v) { + if (x) + ++b; + else + ++a; + } + + // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]] + +#line 200 + while (a) + if (b) + ++b; + else + ++a; + // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]] + +#line 300 + for (unsigned i = 0; i < 100; i++) { + a++; + for (int y : v) + ++b; + } + + // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]] + // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L4:![0-9]*]] + + + // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]} + // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}}) + + // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]} + // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}}) + + // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]} + // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}}) + // + // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]} + // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}}) + // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}}) +}