MCAsmParser: Pull some directive handling out into a helper class, and change

DirectiveMap to be based on MCAsmParserExtension.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108161 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2010-07-12 17:54:38 +00:00
parent eceec05c82
commit 81ea00f45d
3 changed files with 63 additions and 25 deletions

View File

@ -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<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);
@ -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);

View File

@ -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

View File

@ -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<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;
@ -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");