[ms-inline asm] Add a few new APIs to the AsmParser class in support of MS-Style

inline assembly.  For the time being, these will be called directly by clang.
However, in the near future I expect these to be sunk back into the MC layer
and more basic APIs (e.g., getClobbers(), getConstraints(), etc.) will be called
by clang.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165946 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chad Rosier 2012-10-15 17:19:13 +00:00
parent 655fa1225b
commit 8f138d1121
2 changed files with 54 additions and 13 deletions

View File

@ -20,6 +20,7 @@ class MCAsmLexer;
class MCAsmParserExtension; class MCAsmParserExtension;
class MCContext; class MCContext;
class MCExpr; class MCExpr;
class MCParsedAsmOperand;
class MCStreamer; class MCStreamer;
class MCTargetAsmParser; class MCTargetAsmParser;
class SMLoc; class SMLoc;
@ -75,6 +76,25 @@ public:
virtual void setParsingInlineAsm(bool V) = 0; virtual void setParsingInlineAsm(bool V) = 0;
/// ParseStatement - Parse the next statement.
virtual bool ParseStatement() = 0;
/// getNumParsedOperands - Returns the number of MCAsmParsedOperands from the
/// previously parsed statement.
virtual unsigned getNumParsedOperands() = 0;
/// getParsedOperand - Get a MCAsmParsedOperand.
virtual MCParsedAsmOperand &getParsedOperand(unsigned OpNum) = 0;
/// freeParsedOperands - Free the MCAsmParsedOperands.
virtual void freeParsedOperands() = 0;
/// isInstruction - Was the previously parsed statement an instruction?
virtual bool isInstruction() = 0;
/// getOpcode - Get the opcode from the previously parsed instruction.
virtual unsigned getOpcode() = 0;
/// Warning - Emit a warning at the location \p L, with the message \p Msg. /// Warning - Emit a warning at the location \p L, with the message \p Msg.
/// ///
/// \return The return value is true, if warnings are fatal. /// \return The return value is true, if warnings are fatal.

View File

@ -133,9 +133,18 @@ private:
/// IsDarwin - is Darwin compatibility enabled? /// IsDarwin - is Darwin compatibility enabled?
bool IsDarwin; bool IsDarwin;
/// ParsingInlineAsm - are we parsing ms-style inline assembly? /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
bool ParsingInlineAsm; bool ParsingInlineAsm;
/// IsInstruction - Was the last parsed statement an instruction?
bool IsInstruction;
/// ParsedOperands - The parsed operands from the last parsed statement.
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
/// Opcode - The opcode from the last parsed instruction.
unsigned Opcode;
public: public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI); const MCAsmInfo &MAI);
@ -174,7 +183,20 @@ public:
virtual const AsmToken &Lex(); virtual const AsmToken &Lex();
bool ParseStatement();
void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; } void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; }
unsigned getNumParsedOperands() { return ParsedOperands.size(); }
MCParsedAsmOperand &getParsedOperand(unsigned OpNum) {
assert (ParsedOperands.size() > OpNum);
return *ParsedOperands[OpNum];
}
void freeParsedOperands() {
for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
delete ParsedOperands[i];
ParsedOperands.clear();
}
bool isInstruction() { return IsInstruction; }
unsigned getOpcode() { return Opcode; }
bool ParseExpression(const MCExpr *&Res); bool ParseExpression(const MCExpr *&Res);
virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc); virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
@ -186,7 +208,6 @@ public:
private: private:
void CheckForValidSection(); void CheckForValidSection();
bool ParseStatement();
void EatToEndOfLine(); void EatToEndOfLine();
bool ParseCppHashLineFilenameComment(const SMLoc &L); bool ParseCppHashLineFilenameComment(const SMLoc &L);
@ -417,7 +438,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
GenericParser(new GenericAsmParser), PlatformParser(0), GenericParser(new GenericAsmParser), PlatformParser(0),
CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0), CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false),
IsInstruction(false), Opcode(0) {
// Save the old handler. // Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler(); SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext(); SavedDiagContext = SrcMgr.getDiagContext();
@ -1315,12 +1337,11 @@ bool AsmParser::ParseStatement() {
CheckForValidSection(); CheckForValidSection();
// Canonicalize the opcode to lower case. // Canonicalize the opcode to lower case.
SmallString<128> Opcode; SmallString<128> OpcodeStr;
for (unsigned i = 0, e = IDVal.size(); i != e; ++i) for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
Opcode.push_back(tolower(IDVal[i])); OpcodeStr.push_back(tolower(IDVal[i]));
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; bool HadError = getTargetParser().ParseInstruction(OpcodeStr.str(), IDLoc,
bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
ParsedOperands); ParsedOperands);
// Dump the parsed representation, if requested. // Dump the parsed representation, if requested.
@ -1352,17 +1373,17 @@ bool AsmParser::ParseStatement() {
// If parsing succeeded, match the instruction. // If parsing succeeded, match the instruction.
if (!HadError) { if (!HadError) {
unsigned Opcode;
unsigned ErrorInfo; unsigned ErrorInfo;
HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Opcode, HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Opcode,
ParsedOperands, ParsedOperands, Out,
Out, ErrorInfo, ErrorInfo,
ParsingInlineAsm); ParsingInlineAsm);
} }
// Free any parsed operands. // Free any parsed operands. If parsing ms-style inline assembly it is the
for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) // responsibility of the caller (i.e., clang) to free the parsed operands.
delete ParsedOperands[i]; if (!ParsingInlineAsm)
freeParsedOperands();
// Don't skip the rest of the line, the instruction parser is responsible for // Don't skip the rest of the line, the instruction parser is responsible for
// that. // that.