Index: include/llvm/MC/MCObjectStreamer.h =================================================================== --- include/llvm/MC/MCObjectStreamer.h +++ include/llvm/MC/MCObjectStreamer.h @@ -117,6 +117,8 @@ unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName) override; + void EmitStabs(StringRef Str, unsigned Type, unsigned Other, unsigned Desc, + unsigned Value) override; void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize); Index: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -642,6 +642,10 @@ unsigned Isa, unsigned Discriminator, StringRef FileName); + /// \brief This implements the '.stabs' assembler directive. + virtual void EmitStabs(StringRef Str, unsigned Type, unsigned Other, + unsigned Desc, unsigned Value); + /// \brief Associate a filename with a specified logical file number. This /// implements the '.cv_file 4 "foo.c"' assembler directive. virtual unsigned EmitCVFileDirective(unsigned FileNo, StringRef Filename); Index: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -197,6 +197,8 @@ unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName) override; + void EmitStabs(StringRef Str, unsigned Type, unsigned Other, unsigned Desc, + unsigned Value) override; MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override; unsigned EmitCVFileDirective(unsigned FileNo, StringRef Filename) override; @@ -962,6 +964,13 @@ Isa, Discriminator, FileName); } +void MCAsmStreamer::EmitStabs(StringRef Str, unsigned Type, unsigned Other, + unsigned Desc, unsigned Value) { + OS << "\t.stabs\t" + << "\"" << Str << "\"" + << "," << Type << "," << Other << "," << Desc << "," << Value; +} + MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) { // Always use the zeroth line table, since asm syntax only supports one line // table for now. Index: lib/MC/MCObjectStreamer.cpp =================================================================== --- lib/MC/MCObjectStreamer.cpp +++ lib/MC/MCObjectStreamer.cpp @@ -309,6 +309,11 @@ Isa, Discriminator, FileName); } +void MCObjectStreamer::EmitStabs(StringRef Str, unsigned Type, unsigned Other, + unsigned Desc, unsigned Value) { + this->MCStreamer::EmitStabs(Str, Type, Other, Desc, Value); +} + static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A, const MCSymbol *B) { MCContext &Context = OS.getContext(); Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -3097,7 +3097,34 @@ /// parseDirectiveStabs /// ::= .stabs string, number, number, number bool AsmParser::parseDirectiveStabs() { - return TokError("unsupported directive '.stabs'"); + std::string ErrorMsg = "Unexpexted format, expected format is: .stabs " + "string, number, number, number"; + + if (getLexer().is(AsmToken::EndOfStatement)) + return TokError(ErrorMsg); + + if (getLexer().isNot(AsmToken::String)) + return TokError(ErrorMsg); + StringRef Str = Lexer.getTok().getStringContents(); + Lex(); // Eat string + + unsigned Number[4]; + for (int i = 0; i < 4; ++i) { + if (getLexer().isNot(AsmToken::Comma)) + return TokError(ErrorMsg); + Lex(); // Eat comma + + if (getLexer().isNot(AsmToken::Integer)) + return TokError(ErrorMsg); + Number[i] = getLexer().getTok().getIntVal(); + Lex(); // Eat integer number + } + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError(ErrorMsg); + + getStreamer().EmitStabs(Str, Number[0], Number[1], Number[2], Number[3]); + + return false; } /// parseDirectiveCVFile Index: lib/MC/MCStreamer.cpp =================================================================== --- lib/MC/MCStreamer.cpp +++ lib/MC/MCStreamer.cpp @@ -158,6 +158,9 @@ Discriminator); } +void MCStreamer::EmitStabs(StringRef Str, unsigned Type, unsigned Other, + unsigned Desc, unsigned Value) {} + MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); if (!Table.getLabel()) {