aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCCodeView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCCodeView.cpp')
-rw-r--r--llvm/lib/MC/MCCodeView.cpp88
1 files changed, 52 insertions, 36 deletions
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index a27ef64..f09997e 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -275,32 +275,35 @@ void CodeViewContext::addLineEntry(const MCCVLoc &LineEntry) {
std::vector<MCCVLoc>
CodeViewContext::getFunctionLineEntries(unsigned FuncId) {
std::vector<MCCVLoc> FilteredLines;
- auto I = MCCVLineStartStop.find(FuncId);
- if (I != MCCVLineStartStop.end()) {
- MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId);
- for (size_t Idx = I->second.first, End = I->second.second; Idx != End;
- ++Idx) {
- unsigned LocationFuncId = MCCVLines[Idx].getFunctionId();
- if (LocationFuncId == FuncId) {
- // This was a .cv_loc directly for FuncId, so record it.
- FilteredLines.push_back(MCCVLines[Idx]);
- } else {
- // Check if the current location is inlined in this function. If it is,
- // synthesize a statement .cv_loc at the original inlined call site.
- auto I = SiteInfo->InlinedAtMap.find(LocationFuncId);
- if (I != SiteInfo->InlinedAtMap.end()) {
- MCCVFunctionInfo::LineInfo &IA = I->second;
- // Only add the location if it differs from the previous location.
- // Large inlined calls will have many .cv_loc entries and we only need
- // one line table entry in the parent function.
- if (FilteredLines.empty() ||
- FilteredLines.back().getFileNum() != IA.File ||
- FilteredLines.back().getLine() != IA.Line ||
- FilteredLines.back().getColumn() != IA.Col) {
- FilteredLines.push_back(MCCVLoc(
- MCCVLines[Idx].getLabel(),
- FuncId, IA.File, IA.Line, IA.Col, false, false));
- }
+ size_t LocBegin;
+ size_t LocEnd;
+ std::tie(LocBegin, LocEnd) = getLineExtentIncludingInlinees(FuncId);
+ if (LocBegin >= LocEnd) {
+ return FilteredLines;
+ }
+
+ MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId);
+ for (size_t Idx = LocBegin; Idx != LocEnd; ++Idx) {
+ unsigned LocationFuncId = MCCVLines[Idx].getFunctionId();
+ if (LocationFuncId == FuncId) {
+ // This was a .cv_loc directly for FuncId, so record it.
+ FilteredLines.push_back(MCCVLines[Idx]);
+ } else {
+ // Check if the current location is inlined in this function. If it is,
+ // synthesize a statement .cv_loc at the original inlined call site.
+ auto I = SiteInfo->InlinedAtMap.find(LocationFuncId);
+ if (I != SiteInfo->InlinedAtMap.end()) {
+ MCCVFunctionInfo::LineInfo &IA = I->second;
+ // Only add the location if it differs from the previous location.
+ // Large inlined calls will have many .cv_loc entries and we only need
+ // one line table entry in the parent function.
+ if (FilteredLines.empty() ||
+ FilteredLines.back().getFileNum() != IA.File ||
+ FilteredLines.back().getLine() != IA.Line ||
+ FilteredLines.back().getColumn() != IA.Col) {
+ FilteredLines.push_back(MCCVLoc(MCCVLines[Idx].getLabel(), FuncId,
+ IA.File, IA.Line, IA.Col, false,
+ false));
}
}
}
@@ -316,6 +319,26 @@ std::pair<size_t, size_t> CodeViewContext::getLineExtent(unsigned FuncId) {
return I->second;
}
+std::pair<size_t, size_t>
+CodeViewContext::getLineExtentIncludingInlinees(unsigned FuncId) {
+ size_t LocBegin;
+ size_t LocEnd;
+ std::tie(LocBegin, LocEnd) = getLineExtent(FuncId);
+
+ // Include all child inline call sites in our extent.
+ MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId);
+ if (SiteInfo) {
+ for (auto &KV : SiteInfo->InlinedAtMap) {
+ unsigned ChildId = KV.first;
+ auto Extent = getLineExtent(ChildId);
+ LocBegin = std::min(LocBegin, Extent.first);
+ LocEnd = std::max(LocEnd, Extent.second);
+ }
+ }
+
+ return {LocBegin, LocEnd};
+}
+
ArrayRef<MCCVLoc> CodeViewContext::getLinesForExtent(size_t L, size_t R) {
if (R <= L)
return std::nullopt;
@@ -463,16 +486,7 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
MCCVInlineLineTableFragment &Frag) {
size_t LocBegin;
size_t LocEnd;
- std::tie(LocBegin, LocEnd) = getLineExtent(Frag.SiteFuncId);
-
- // Include all child inline call sites in our .cv_loc extent.
- MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(Frag.SiteFuncId);
- for (auto &KV : SiteInfo->InlinedAtMap) {
- unsigned ChildId = KV.first;
- auto Extent = getLineExtent(ChildId);
- LocBegin = std::min(LocBegin, Extent.first);
- LocEnd = std::max(LocEnd, Extent.second);
- }
+ std::tie(LocBegin, LocEnd) = getLineExtentIncludingInlinees(Frag.SiteFuncId);
if (LocBegin >= LocEnd)
return;
@@ -507,6 +521,8 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
LastSourceLoc.File = Frag.StartFileId;
LastSourceLoc.Line = Frag.StartLineNum;
+ MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(Frag.SiteFuncId);
+
SmallVectorImpl<char> &Buffer = Frag.getContents();
Buffer.clear(); // Clear old contents if we went through relaxation.
for (const MCCVLoc &Loc : Locs) {