diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index 0ad7941be2c..bbf2ebfbed5 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -26,6 +26,7 @@ namespace llvm { class AsmCond; class AsmToken; +class MCAsmParserExtension; class MCContext; class MCExpr; class MCInst; @@ -43,6 +44,7 @@ private: MCContext &Ctx; MCStreamer &Out; SourceMgr &SrcMgr; + MCAsmParserExtension *GenericParser; TargetAsmParser *TargetParser; /// This is the current buffer index we're lexing from as managed by the @@ -56,18 +58,20 @@ private: /// invoked after the directive identifier is read and is responsible for /// parsing and validating the rest of the directive. The handler is passed /// in the directive name and the location of the directive keyword. - StringMap DirectiveMap; + StringMap > DirectiveMap; public: AsmParser(const Target &T, SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); ~AsmParser(); bool Run(bool NoInitialTextSection, bool NoFinalize = false); - - void AddDirectiveHandler(StringRef Directive, - bool (AsmParser::*Handler)(StringRef, SMLoc)) { - DirectiveMap[Directive] = Handler; + + void AddDirectiveHandler(MCAsmParserExtension *Object, + StringRef Directive, + DirectiveHandler Handler) { + DirectiveMap[Directive] = std::make_pair(Object, Handler); } + public: TargetAsmParser &getTargetParser() const { return *TargetParser; } void setTargetParser(TargetAsmParser &P); @@ -155,10 +159,6 @@ private: bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else" bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif - bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file" - bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line" - bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc" - /// ParseEscapedString - Parse the current token as a string which may include /// escaped characters and return the string contents. bool ParseEscapedString(std::string &Data); diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 176c3a30579..d78f512a4ad 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -15,15 +15,21 @@ namespace llvm { class AsmToken; class MCAsmLexer; +class MCAsmParserExtension; class MCContext; class MCExpr; class MCStreamer; class SMLoc; +class StringRef; class Twine; /// MCAsmParser - Generic assembler parser interface, for use by target specific /// assembly parsers. class MCAsmParser { +public: + typedef bool (MCAsmParserExtension::*DirectiveHandler)(StringRef, SMLoc); + +private: MCAsmParser(const MCAsmParser &); // DO NOT IMPLEMENT void operator=(const MCAsmParser &); // DO NOT IMPLEMENT protected: // Can only create subclasses. @@ -32,11 +38,15 @@ protected: // Can only create subclasses. public: virtual ~MCAsmParser(); + virtual void AddDirectiveHandler(MCAsmParserExtension *Object, + StringRef Directive, + DirectiveHandler Handler) = 0; + virtual MCAsmLexer &getLexer() = 0; virtual MCContext &getContext() = 0; - /// getSteamer - Return the output streamer for the assembler. + /// getStreamer - Return the output streamer for the assembler. virtual MCStreamer &getStreamer() = 0; /// Warning - Emit a warning at the location \arg L, with the message \arg diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a06333b1f88..ea63a2227b4 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -30,21 +30,48 @@ using namespace llvm; +namespace { + +/// \brief Generic implementations of directive handling, etc. which is shared +/// (or the default, at least) for all assembler parser. +class GenericAsmParser : public MCAsmParserExtension { +public: + GenericAsmParser() {} + + virtual void Initialize(MCAsmParser &Parser) { + // Call the base implementation. + this->MCAsmParserExtension::Initialize(Parser); + + // Debugging directives. + Parser.AddDirectiveHandler(this, ".file", MCAsmParser::DirectiveHandler( + &GenericAsmParser::ParseDirectiveFile)); + Parser.AddDirectiveHandler(this, ".line", MCAsmParser::DirectiveHandler( + &GenericAsmParser::ParseDirectiveLine)); + Parser.AddDirectiveHandler(this, ".loc", MCAsmParser::DirectiveHandler( + &GenericAsmParser::ParseDirectiveLoc)); + } + + bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file" + bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line" + bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc" +}; + +} + enum { DEFAULT_ADDRSPACE = 0 }; AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, const MCAsmInfo &_MAI) - : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), TargetParser(0), - CurBuffer(0) { + : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), + GenericParser(new GenericAsmParser), TargetParser(0), CurBuffer(0) { Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); - - // Debugging directives. - AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile); - AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine); - AddDirectiveHandler(".loc", &AsmParser::ParseDirectiveLoc); + + // Initialize the generic parser. + GenericParser->Initialize(*this); } AsmParser::~AsmParser() { + delete GenericParser; } void AsmParser::setTargetParser(TargetAsmParser &P) { @@ -787,11 +814,12 @@ bool AsmParser::ParseStatement() { if (IDVal == ".secure_log_reset") return ParseDirectiveDarwinSecureLogReset(IDLoc); - // Look up the handler in the handler table, - bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal]; - if (Handler) - return (this->*Handler)(IDVal, IDLoc); - + // Look up the handler in the handler table. + std::pair Handler = + DirectiveMap.lookup(IDVal); + if (Handler.first) + return (Handler.first->*Handler.second)(IDVal, IDLoc); + // Target hook for parsing target specific directives. if (!getTargetParser().ParseDirective(ID)) return false; @@ -1895,7 +1923,7 @@ bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { /// ParseDirectiveFile /// ::= .file [number] string -bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { +bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { // FIXME: I'm not sure what this is. int64_t FileNumber = -1; if (getLexer().is(AsmToken::Integer)) { @@ -1926,7 +1954,7 @@ bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { /// ParseDirectiveLine /// ::= .line [number] -bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { +bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) { if (getLexer().isNot(AsmToken::Integer)) return TokError("unexpected token in '.line' directive"); @@ -1947,7 +1975,7 @@ bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { /// ParseDirectiveLoc /// ::= .loc number [number [number]] -bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { +bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::Integer)) return TokError("unexpected token in '.loc' directive");