aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2012-10-15 17:19:13 +0000
committerChad Rosier <mcrosier@apple.com>2012-10-15 17:19:13 +0000
commit8f138d1121730007f973131ca79a06a58f981011 (patch)
tree63a0790f0dfc2543dd3c60e31d8033b68671403f
parent655fa1225b49dc3d8c2f1eed049eaf47ceb3ae8d (diff)
[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
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h20
-rw-r--r--lib/MC/MCParser/AsmParser.cpp47
2 files changed, 54 insertions, 13 deletions
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index a572e6d5f0..08758cda22 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -20,6 +20,7 @@ class MCAsmLexer;
class MCAsmParserExtension;
class MCContext;
class MCExpr;
+class MCParsedAsmOperand;
class MCStreamer;
class MCTargetAsmParser;
class SMLoc;
@@ -75,6 +76,25 @@ public:
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.
///
/// \return The return value is true, if warnings are fatal.
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 8bf017a1a0..0a8053121c 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -133,9 +133,18 @@ private:
/// IsDarwin - is Darwin compatibility enabled?
bool IsDarwin;
- /// ParsingInlineAsm - are we parsing ms-style inline assembly?
+ /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
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:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI);
@@ -174,7 +183,20 @@ public:
virtual const AsmToken &Lex();
+ bool ParseStatement();
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);
virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
@@ -186,7 +208,6 @@ public:
private:
void CheckForValidSection();
- bool ParseStatement();
void EatToEndOfLine();
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),
GenericParser(new GenericAsmParser), PlatformParser(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.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -1315,12 +1337,11 @@ bool AsmParser::ParseStatement() {
CheckForValidSection();
// Canonicalize the opcode to lower case.
- SmallString<128> Opcode;
+ SmallString<128> OpcodeStr;
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(Opcode.str(), IDLoc,
+ bool HadError = getTargetParser().ParseInstruction(OpcodeStr.str(), IDLoc,
ParsedOperands);
// Dump the parsed representation, if requested.
@@ -1352,17 +1373,17 @@ bool AsmParser::ParseStatement() {
// If parsing succeeded, match the instruction.
if (!HadError) {
- unsigned Opcode;
unsigned ErrorInfo;
HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Opcode,
- ParsedOperands,
- Out, ErrorInfo,
+ ParsedOperands, Out,
+ ErrorInfo,
ParsingInlineAsm);
}
- // Free any parsed operands.
- for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
- delete ParsedOperands[i];
+ // Free any parsed operands. If parsing ms-style inline assembly it is the
+ // responsibility of the caller (i.e., clang) to free the parsed operands.
+ if (!ParsingInlineAsm)
+ freeParsedOperands();
// Don't skip the rest of the line, the instruction parser is responsible for
// that.