# RUN: llvm-mc -filetype=obj %s -o %t.obj -triple x86_64-windows-msvc
# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe -pdb:%t.pdb -debug
# RUN: llvm-symbolizer --obj=%t.exe --relative-address \
-# RUN: 0x1014 0x1018 0x101c 0x1023 0x1024 \
+# RUN: 0x1014 0x1015 0x1018 0x1019 0x101c 0x101d 0x1023 0x1024 \
# RUN: 0x1037 0x103A 0x104B 0x104E | FileCheck %s
-# Compiled from this cpp code, with modifications to add extra inline line and
+# Compiled from this cpp code, with modifications to add extra inline line and
# file changes:
# clang -cc1 -triple x86_64-windows-msvc -gcodeview -S test.cpp
#
# CHECK-NEXT: C:\src\test.cpp:6:0
# CHECK-NEXT: main
# CHECK-NEXT: C:\src\test.cpp:10:11
+
+# CHECK: inlinee_1
+# CHECK-NEXT: C:\src\test.cpp:6:0
+# CHECK-NEXT: main
+# CHECK-NEXT: C:\src\test.cpp:10:11
movl 16(%rsp), %eax
# Add a line change here.
# CHECK-NEXT: C:\src\test.cpp:7:0
# CHECK-NEXT: main
# CHECK-NEXT: C:\src\test.cpp:10:11
+
+# CHECK: inlinee_1
+# CHECK-NEXT: C:\src\test.cpp:7:0
+# CHECK-NEXT: main
+# CHECK-NEXT: C:\src\test.cpp:10:11
movl %eax, 20(%rsp)
.Ltmp1:
.cv_inline_site_id 2 within 1 inlined_at 1 6 10
# CHECK-NEXT: C:\src\test.cpp:6:0
# CHECK-NEXT: main
# CHECK-NEXT: C:\src\test.cpp:10:11
+
+# CHECK: inlinee_2
+# CHECK-NEXT: C:\src\test.cpp:2:0
+# CHECK-NEXT: inlinee_1
+# CHECK-NEXT: C:\src\test.cpp:6:0
+# CHECK-NEXT: main
+# CHECK-NEXT: C:\src\test.cpp:10:11
movl 20(%rsp), %eax
.cv_loc 2 1 2 12 # test.cpp:2:12
addl $1, %eax
LineOffset = 0;
FileOffset = 0;
uint32_t CodeOffset = 0;
+ Optional<uint32_t> CodeOffsetBase;
+ Optional<uint32_t> CodeOffsetEnd;
+ Optional<uint32_t> CurLineOffset;
+ Optional<uint32_t> NextLineOffset;
+ Optional<uint32_t> NextFileOffset;
+ auto UpdateCodeOffset = [&](uint32_t Delta) {
+ if (!CodeOffsetBase)
+ CodeOffsetBase = CodeOffset;
+ else if (!CodeOffsetEnd)
+ CodeOffsetEnd = *CodeOffsetBase + Delta;
+ };
+ auto UpdateLineOffset = [&](int32_t Delta) {
+ LineOffset += Delta;
+ if (!CodeOffsetBase || !CurLineOffset)
+ CurLineOffset = LineOffset;
+ else
+ NextLineOffset = LineOffset;
+ };
+ auto UpdateFileOffset = [&](uint32_t Offset) {
+ if (!CodeOffsetBase)
+ FileOffset = Offset;
+ else
+ NextFileOffset = Offset;
+ };
+ auto ValidateAndReset = [&]() {
+ // Current range is finished. Check if OffsetInFunc is in the range.
+ if (CodeOffsetBase && CodeOffsetEnd && CurLineOffset) {
+ if (CodeOffsetBase <= OffsetInFunc && OffsetInFunc < CodeOffsetEnd) {
+ LineOffset = *CurLineOffset;
+ return true;
+ }
+ // Set base, end, file offset and line offset for next range.
+ if (NextFileOffset)
+ FileOffset = *NextFileOffset;
+ CurLineOffset = NextLineOffset ? NextLineOffset : None;
+ CodeOffsetBase = CodeOffsetEnd;
+ CodeOffsetEnd = NextLineOffset = NextFileOffset = None;
+ }
+ return false;
+ };
for (const auto &Annot : Sym.annotations()) {
switch (Annot.OpCode) {
case BinaryAnnotationsOpCode::CodeOffset:
case BinaryAnnotationsOpCode::ChangeCodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeLength:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
CodeOffset += Annot.U1;
+ UpdateCodeOffset(Annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ UpdateCodeOffset(Annot.U1);
break;
case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
CodeOffset += Annot.U2;
+ UpdateCodeOffset(Annot.U2);
+ UpdateCodeOffset(Annot.U1);
break;
case BinaryAnnotationsOpCode::ChangeLineOffset:
+ UpdateLineOffset(Annot.S1);
+ break;
case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
CodeOffset += Annot.U1;
- LineOffset += Annot.S1;
+ UpdateCodeOffset(Annot.U1);
+ UpdateLineOffset(Annot.S1);
break;
case BinaryAnnotationsOpCode::ChangeFile:
- FileOffset = Annot.U1;
+ UpdateFileOffset(Annot.U1);
break;
default:
break;
}
- if (CodeOffset >= OffsetInFunc)
+ if (ValidateAndReset())
return;
}
}