namespace llvm {
class AsmCond;
class AsmToken;
+class MCAsmParserExtension;
class MCContext;
class MCExpr;
class MCInst;
MCContext &Ctx;
MCStreamer &Out;
SourceMgr &SrcMgr;
+ MCAsmParserExtension *GenericParser;
TargetAsmParser *TargetParser;
/// This is the current buffer index we're lexing from as managed by the
/// 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<bool(AsmParser::*)(StringRef, SMLoc)> DirectiveMap;
+ StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > 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);
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);
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.
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
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) {
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<MCAsmParserExtension*, DirectiveHandler> 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;
/// 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)) {
/// 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");
/// 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");