// 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);
+}
/// 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.
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<Metadata *, 4> Args;
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) {
}
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<const clang::Attr *> Attrs,
- llvm::DebugLoc Location) {
+ llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc) {
// Identify loop hint attributes from Attrs.
for (const auto *Attr : Attrs) {
}
/// Stage the attributes.
- push(Header, Location);
+ push(Header, StartLoc, EndLoc);
}
void LoopInfoStack::pop() {
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; }
/// \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<const Attr *> Attrs,
- llvm::DebugLoc Location = llvm::DebugLoc());
+ llvm::ArrayRef<const Attr *> Attrs, llvm::DebugLoc StartLoc,
+ llvm::DebugLoc EndLoc);
/// \brief End the current loop.
void pop();
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.
// 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);
{
LexicalScope ForScope(*this, S.getSourceRange());
- llvm::DebugLoc DL = Builder.getCurrentDebugLocation();
-
// Evaluate the first part before the loop.
if (S.getInit())
EmitStmt(S.getInit());
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
LexicalScope ForScope(*this, S.getSourceRange());
- llvm::DebugLoc DL = Builder.getCurrentDebugLocation();
-
// Evaluate the first pieces before the loop.
EmitStmt(S.getRangeStmt());
EmitStmt(S.getBeginStmt());
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.
// 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.
// 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) {
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();
+}
OffsetValue);
}
+ /// Converts Location to a DebugLoc, if debug information is enabled.
+ llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
+
+
//===--------------------------------------------------------------------===//
// Declaration Emission
//===--------------------------------------------------------------------===//
// 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: [[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]], [[LDBG2:![0-9]*]]}
- // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, 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]], [[LDBG3:![0-9]*]]}
- // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, 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]], [[LDBG4:![0-9]*]]}
- // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, 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: !{{.*}})
}
--- /dev/null
+// 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: !{{.*}})
+}