diff options
author | Reid Kleckner <rnk@google.com> | 2016-02-02 17:41:18 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-02-02 17:41:18 +0000 |
commit | 617bba8af8b0582948a04c2c93db81226204ba25 (patch) | |
tree | 146f0ae7de74477f0a1ad82ca8ede476821001ec /lib | |
parent | 27751b528767b68b886e31af3a28b88e17e22be1 (diff) |
[codeview] Wire up the .cv_inline_linetable directive
This directive emits the binary annotations that describe line and code
deltas in inlined call sites. Single-stepping through inlined frames in
windbg now works.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259535 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 60 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/CodeViewDebug.h | 11 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 9 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 19 | ||||
-rw-r--r-- | lib/MC/MCCodeView.cpp | 121 | ||||
-rw-r--r-- | lib/MC/MCFragment.cpp | 14 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 7 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 13 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 2 |
9 files changed, 215 insertions, 41 deletions
diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index e3c48296f34..de12fc38138 100644 --- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -96,6 +96,7 @@ CodeViewDebug::InlineSite &CodeViewDebug::getInlineSite(const DILocation *Loc) { InlineSite &Site = Insertion.first->second; Site.SiteFuncId = NextFuncId++; Site.Inlinee = Loc->getScope()->getSubprogram(); + InlinedSubprograms.insert(Loc->getScope()->getSubprogram()); } return Insertion.first->second; } @@ -188,6 +189,9 @@ void CodeViewDebug::endModule() { // of the payload followed by the payload itself. The subsections are 4-byte // aligned. + // Make a subsection for all the inlined subprograms. + emitInlineeLinesSubsection(); + // Emit per-function debug information. for (auto &P : FnDebugInfo) emitDebugInfoForFunction(P.first, P.second); @@ -257,6 +261,39 @@ void CodeViewDebug::emitTypeInformation() { } } +void CodeViewDebug::emitInlineeLinesSubsection() { + if (InlinedSubprograms.empty()) + return; + + MCStreamer &OS = *Asm->OutStreamer; + MCSymbol *InlineBegin = Asm->MMI->getContext().createTempSymbol(), + *InlineEnd = Asm->MMI->getContext().createTempSymbol(); + + OS.AddComment("Inlinee lines subsection"); + OS.EmitIntValue(unsigned(ModuleSubstreamKind::InlineeLines), 4); + OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 4); + OS.EmitLabel(InlineBegin); + + // We don't provide any extra file info. + // FIXME: Find out if debuggers use this info. + OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4); + + for (const DISubprogram *SP : InlinedSubprograms) { + TypeIndex TypeId = SubprogramToFuncId[SP]; + unsigned FileId = maybeRecordFile(SP->getFile()); + OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " + + SP->getFilename() + Twine(':') + Twine(SP->getLine())); + // The filechecksum table uses 8 byte entries for now, and file ids start at + // 1. + unsigned FileOffset = (FileId - 1) * 8; + OS.EmitIntValue(TypeId.getIndex(), 4); + OS.EmitIntValue(FileOffset, 4); + OS.EmitIntValue(SP->getLine(), 4); + } + + OS.EmitLabel(InlineEnd); +} + static void EmitLabelDiff(MCStreamer &Streamer, const MCSymbol *From, const MCSymbol *To, unsigned int Size = 4) { @@ -269,6 +306,18 @@ static void EmitLabelDiff(MCStreamer &Streamer, Streamer.EmitValue(AddrDelta, Size); } +void CodeViewDebug::collectInlineSiteChildren( + SmallVectorImpl<unsigned> &Children, const FunctionInfo &FI, + const InlineSite &Site) { + for (const DILocation *ChildSiteLoc : Site.ChildSites) { + auto I = FI.InlineSites.find(ChildSiteLoc); + assert(I != FI.InlineSites.end()); + const InlineSite &ChildSite = I->second; + Children.push_back(ChildSite.SiteFuncId); + collectInlineSiteChildren(Children, FI, ChildSite); + } +} + void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, const InlineSite &Site) { @@ -290,7 +339,13 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, Asm->OutStreamer->EmitBytes( StringRef(reinterpret_cast<const char *>(&SiteBytes), sizeof(SiteBytes))); - // FIXME: annotations + unsigned FileId = maybeRecordFile(Site.Inlinee->getFile()); + unsigned StartLineNum = Site.Inlinee->getLine(); + SmallVector<unsigned, 3> SecondaryFuncIds; + collectInlineSiteChildren(SecondaryFuncIds, FI, Site); + + OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum, + FI.Begin, SecondaryFuncIds); OS.EmitLabel(InlineEnd); @@ -367,7 +422,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, } Asm->OutStreamer->EmitLabel(SymbolsEnd); // Every subsection must be aligned to a 4-byte boundary. - Asm->OutStreamer->EmitFill((-FuncName.size()) % 4, 0); + Asm->OutStreamer->EmitValueToAlignment(4); // We have an assembler directive that takes care of the whole line table. Asm->OutStreamer->EmitCVLinetableDirective(FI.FuncId, Fn, FI.End); @@ -383,6 +438,7 @@ void CodeViewDebug::beginFunction(const MachineFunction *MF) { assert(FnDebugInfo.count(GV) == false); CurFn = &FnDebugInfo[GV]; CurFn->FuncId = NextFuncId++; + CurFn->Begin = Asm->getFunctionBegin(); // Find the end of the function prolog. // FIXME: is there a simpler a way to do this? Can we just search diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/lib/CodeGen/AsmPrinter/CodeViewDebug.h index 4883905e907..d9f38f3eaf8 100644 --- a/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -48,7 +48,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler { MapVector<const DILocation *, InlineSite> InlineSites; DebugLoc LastLoc; - MCSymbol *End = nullptr; + const MCSymbol *Begin = nullptr; + const MCSymbol *End = nullptr; unsigned FuncId = 0; unsigned LastFileId = 0; bool HaveLineInfo = false; @@ -59,6 +60,10 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler { InlineSite &getInlineSite(const DILocation *Loc); + static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, + const FunctionInfo &FI, + const InlineSite &Site); + /// Remember some debug info about each function. Keep it in a stable order to /// emit at the end of the TU. MapVector<const Function *, FunctionInfo> FnDebugInfo; @@ -66,6 +71,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler { /// Map from DIFile to .cv_file id. DenseMap<const DIFile *, unsigned> FileIdMap; + SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; + DenseMap<const DISubprogram *, codeview::TypeIndex> SubprogramToFuncId; unsigned TypeCount = 0; @@ -93,6 +100,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler { void emitTypeInformation(); + void emitInlineeLinesSubsection(); + void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 1bac42a8d09..712b7a938be 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -207,6 +207,7 @@ public: const MCSymbol *FnEnd) override; void EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, + const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) override; void EmitCVStringTableDirective() override; void EmitCVFileChecksumsDirective() override; @@ -1019,9 +1020,10 @@ void MCAsmStreamer::EmitCVLinetableDirective(unsigned FunctionId, void MCAsmStreamer::EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - ArrayRef<unsigned> SecondaryFunctionIds) { + const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) { OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId - << ' ' << SourceLineNum; + << ' ' << SourceLineNum << ' '; + FnStartSym->print(OS, MAI); if (!SecondaryFunctionIds.empty()) { OS << " contains"; for (unsigned SecondaryFunctionId : SecondaryFunctionIds) @@ -1029,7 +1031,8 @@ void MCAsmStreamer::EmitCVInlineLinetableDirective( } EmitEOL(); this->MCStreamer::EmitCVInlineLinetableDirective( - PrimaryFunctionId, SourceFileId, SourceLineNum, SecondaryFunctionIds); + PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, + SecondaryFunctionIds); } void MCAsmStreamer::EmitCVStringTableDirective() { diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 6965b1b037f..9a55ef3931e 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -15,6 +15,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCCodeView.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" @@ -300,6 +301,8 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, return cast<MCDwarfLineAddrFragment>(F).getContents().size(); case MCFragment::FT_DwarfFrame: return cast<MCDwarfCallFrameFragment>(F).getContents().size(); + case MCFragment::FT_CVInlineLines: + return cast<MCCVInlineLineTableFragment>(F).getContents().size(); case MCFragment::FT_Dummy: llvm_unreachable("Should not have been added"); } @@ -537,6 +540,11 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, OW->writeBytes(CF.getContents()); break; } + case MCFragment::FT_CVInlineLines: { + const auto &OF = cast<MCCVInlineLineTableFragment>(F); + OW->writeBytes(OF.getContents()); + break; + } case MCFragment::FT_Dummy: llvm_unreachable("Should not have been added"); } @@ -813,6 +821,13 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, return OldSize != Data.size(); } +bool MCAssembler::relaxCVInlineLineTable(MCAsmLayout &Layout, + MCCVInlineLineTableFragment &F) { + unsigned OldSize = F.getContents().size(); + getContext().getCVContext().encodeInlineLineTable(Layout, F); + return OldSize != F.getContents().size(); +} + bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) { // Holds the first fragment which needed relaxing during this layout. It will // remain NULL if none were relaxed. @@ -844,6 +859,10 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) { case MCFragment::FT_LEB: RelaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(I)); break; + case MCFragment::FT_CVInlineLines: + RelaxedFrag = + relaxCVInlineLineTable(Layout, *cast<MCCVInlineLineTableFragment>(I)); + break; } if (RelaxedFrag && !FirstRelaxedFragment) FirstRelaxedFragment = &*I; diff --git a/lib/MC/MCCodeView.cpp b/lib/MC/MCCodeView.cpp index a876470b826..ea226f7769e 100644 --- a/lib/MC/MCCodeView.cpp +++ b/lib/MC/MCCodeView.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCCodeView.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" @@ -226,40 +227,110 @@ static uint32_t encodeSignedNumber(uint32_t Data) { void CodeViewContext::emitInlineLineTableForFunction( MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, - unsigned SourceLineNum, ArrayRef<unsigned> SecondaryFunctionIds) { - std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(PrimaryFunctionId); - std::vector<std::pair<BinaryAnnotationsOpCode, uint32_t>> Annotations; + unsigned SourceLineNum, const MCSymbol *FnStartSym, + ArrayRef<unsigned> SecondaryFunctionIds) { + // Create and insert a fragment into the current section that will be encoded + // later. + new MCCVInlineLineTableFragment( + PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, + SecondaryFunctionIds, OS.getCurrentSectionOnly()); +} + +unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin, + const MCSymbol *End) { + MCContext &Ctx = Layout.getAssembler().getContext(); + MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; + const MCExpr *BeginRef = MCSymbolRefExpr::create(Begin, Variant, Ctx), + *EndRef = MCSymbolRefExpr::create(End, Variant, Ctx); + const MCExpr *AddrDelta = + MCBinaryExpr::create(MCBinaryExpr::Sub, EndRef, BeginRef, Ctx); + int64_t Result; + bool Success = AddrDelta->evaluateKnownAbsolute(Result, Layout); + assert(Success && "failed to evaluate label difference as absolute"); + (void)Success; + assert(Result >= 0 && "negative label difference requested"); + assert(Result < UINT_MAX && "label difference greater than 2GB"); + return unsigned(Result); +} - const MCCVLineEntry *LastLoc = nullptr; - unsigned LastFileId = SourceFileId; - unsigned LastLineNum = SourceLineNum; +void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, + MCCVInlineLineTableFragment &Frag) { + size_t LocBegin; + size_t LocEnd; + std::tie(LocBegin, LocEnd) = getLineExtent(Frag.SiteFuncId); + for (unsigned SecondaryId : Frag.SecondaryFuncs) { + auto Extent = getLineExtent(SecondaryId); + LocBegin = std::min(LocBegin, Extent.first); + LocEnd = std::max(LocEnd, Extent.second); + } + if (LocBegin >= LocEnd) + return; + ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd + 1); + if (Locs.empty()) + return; + SmallSet<unsigned, 8> InlinedFuncIds; + InlinedFuncIds.insert(Frag.SiteFuncId); + InlinedFuncIds.insert(Frag.SecondaryFuncs.begin(), Frag.SecondaryFuncs.end()); + + // Make an artificial start location using the function start and the inlinee + // lines start location information. All deltas start relative to this + // location. + MCCVLineEntry StartLoc(Frag.getFnStartSym(), MCCVLoc(Locs.front())); + StartLoc.setFileNum(Frag.StartFileId); + StartLoc.setLine(Frag.StartLineNum); + const MCCVLineEntry *LastLoc = &StartLoc; + bool WithinFunction = true; + + SmallVectorImpl<char> &Buffer = Frag.getContents(); + Buffer.clear(); // Clear old contents if we went through relaxation. for (const MCCVLineEntry &Loc : Locs) { - if (!LastLoc) { - // TODO ChangeCodeOffset - // TODO ChangeCodeLength + if (!InlinedFuncIds.count(Loc.getFunctionId())) { + // We've hit a cv_loc not attributed to this inline call site. Use this + // label to end the PC range. + if (WithinFunction) { + unsigned Length = + computeLabelDiff(Layout, LastLoc->getLabel(), Loc.getLabel()); + compressAnnotation(ChangeCodeLength, Buffer); + compressAnnotation(Length, Buffer); + } + WithinFunction = false; + continue; } + WithinFunction = true; - if (Loc.getFileNum() != LastFileId) - Annotations.push_back({ChangeFile, Loc.getFileNum()}); + if (Loc.getFileNum() != LastLoc->getFileNum()) { + compressAnnotation(ChangeFile, Buffer); + compressAnnotation(Loc.getFileNum(), Buffer); + } - if (Loc.getLine() != LastLineNum) - Annotations.push_back( - {ChangeLineOffset, encodeSignedNumber(Loc.getLine() - LastLineNum)}); + int LineDelta = Loc.getLine() - LastLoc->getLine(); + if (LineDelta == 0) + continue; + + unsigned EncodedLineDelta = encodeSignedNumber(LineDelta); + unsigned CodeDelta = + computeLabelDiff(Layout, LastLoc->getLabel(), Loc.getLabel()); + if (CodeDelta == 0) { + compressAnnotation(ChangeLineOffset, Buffer); + compressAnnotation(EncodedLineDelta, Buffer); + } else if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) { + // The ChangeCodeOffsetAndLineOffset combination opcode is used when the + // encoded line delta uses 3 or fewer set bits and the code offset fits + // in one nibble. + unsigned Operand = (EncodedLineDelta << 4) | CodeDelta; + compressAnnotation(ChangeCodeOffsetAndLineOffset, Buffer); + compressAnnotation(Operand, Buffer); + } else { + // Otherwise use the separate line and code deltas. + compressAnnotation(ChangeLineOffset, Buffer); + compressAnnotation(EncodedLineDelta, Buffer); + compressAnnotation(ChangeCodeOffset, Buffer); + compressAnnotation(CodeDelta, Buffer); + } LastLoc = &Loc; - LastFileId = Loc.getFileNum(); - LastLineNum = Loc.getLine(); - } - - SmallString<32> Buffer; - for (auto Annotation : Annotations) { - BinaryAnnotationsOpCode Opcode = Annotation.first; - uint32_t Operand = Annotation.second; - compressAnnotation(Opcode, Buffer); - compressAnnotation(Operand, Buffer); } - OS.EmitBytes(Buffer); } // diff --git a/lib/MC/MCFragment.cpp b/lib/MC/MCFragment.cpp index 67f57a5c8fe..bfadfda47f2 100644 --- a/lib/MC/MCFragment.cpp +++ b/lib/MC/MCFragment.cpp @@ -289,6 +289,9 @@ void MCFragment::destroy() { case FT_SafeSEH: delete cast<MCSafeSEHFragment>(this); return; + case FT_CVInlineLines: + delete cast<MCCVInlineLineTableFragment>(this); + return; case FT_Dummy: delete cast<MCDummyFragment>(this); return; @@ -327,9 +330,8 @@ LLVM_DUMP_METHOD void MCFragment::dump() { case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break; case MCFragment::FT_LEB: OS << "MCLEBFragment"; break; case MCFragment::FT_SafeSEH: OS << "MCSafeSEHFragment"; break; - case MCFragment::FT_Dummy: - OS << "MCDummyFragment"; - break; + case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break; + case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break; } OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder @@ -427,6 +429,12 @@ LLVM_DUMP_METHOD void MCFragment::dump() { OS << " Sym:" << F->getSymbol(); break; } + case MCFragment::FT_CVInlineLines: { + const auto *F = cast<MCCVInlineLineTableFragment>(this); + OS << "\n "; + OS << " Sym:" << *F->getFnStartSym(); + break; + } case MCFragment::FT_Dummy: break; } diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 4f0b597b434..4d849049f60 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -386,12 +386,13 @@ void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId, void MCObjectStreamer::EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - ArrayRef<unsigned> SecondaryFunctionIds) { + const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) { getContext().getCVContext().emitInlineLineTableForFunction( - *this, PrimaryFunctionId, SourceFileId, SourceLineNum, + *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, SecondaryFunctionIds); this->MCStreamer::EmitCVInlineLinetableDirective( - PrimaryFunctionId, SourceFileId, SourceLineNum, SecondaryFunctionIds); + PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, + SecondaryFunctionIds); } void MCObjectStreamer::EmitCVStringTableDirective() { diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 621618a5666..9f8027a381e 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -3229,7 +3229,7 @@ bool AsmParser::parseDirectiveCVLinetable() { } /// parseDirectiveCVInlineLinetable -/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum +/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart /// ("contains" SecondaryFunctionId+)? bool AsmParser::parseDirectiveCVInlineLinetable() { int64_t PrimaryFunctionId = getTok().getIntVal(); @@ -3250,6 +3250,12 @@ bool AsmParser::parseDirectiveCVInlineLinetable() { "Line number less than zero in '.cv_inline_linetable' directive"); Lex(); + SMLoc Loc = getLexer().getLoc(); + StringRef FnStartName; + if (parseIdentifier(FnStartName)) + return Error(Loc, "expected identifier in directive"); + MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); + SmallVector<unsigned, 8> SecondaryFunctionIds; if (getLexer().is(AsmToken::Identifier)) { if (getTok().getIdentifier() != "contains") @@ -3268,8 +3274,9 @@ bool AsmParser::parseDirectiveCVInlineLinetable() { } } - getStreamer().EmitCVInlineLinetableDirective( - PrimaryFunctionId, SourceFileId, SourceLineNum, SecondaryFunctionIds); + getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId, + SourceLineNum, FnStartSym, + SecondaryFunctionIds); return false; } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 1f445ca5893..dcb01b4d119 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -198,7 +198,7 @@ void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId, void MCStreamer::EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - ArrayRef<unsigned> SecondaryFunctionIds) {} + const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {} void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) { |