[ms-inline asm] Add a few new APIs to the AsmParser class in support of MS-Style
authorChad Rosier <mcrosier@apple.com>
Mon, 15 Oct 2012 17:19:13 +0000 (17:19 +0000)
committerChad Rosier <mcrosier@apple.com>
Mon, 15 Oct 2012 17:19:13 +0000 (17:19 +0000)
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

include/llvm/MC/MCParser/MCAsmParser.h
lib/MC/MCParser/AsmParser.cpp

index a572e6d5f01491eee529b6dbeef51a393086497b..08758cda2267fd52c0f37518533f612c5262fd80 100644 (file)
@@ -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.
index 8bf017a1a0ad960981ac0b33d4f90ab8a466057b..0a8053121c85ff8fc19d2464a5867aa48450f7e6 100644 (file)
@@ -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.