[ms-inline asm] Remove brackets from around a symbol reference in the target
[oota-llvm.git] / lib / Target / X86 / AsmParser / X86AsmParser.cpp
index 11248bd5d45fd2abae3a1f115d24cadbbef5be2c..aaf571ae9d30a9f14631eb9eb25abf04cfa28502 100644 (file)
@@ -57,8 +57,8 @@ private:
   X86Operand *ParseOperand();
   X86Operand *ParseATTOperand();
   X86Operand *ParseIntelOperand();
-  X86Operand *ParseIntelOffsetOfOperator(SMLoc StartLoc);
-  X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
+  X86Operand *ParseIntelOffsetOfOperator();
+  X86Operand *ParseIntelOperator(unsigned OpKind);
   X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
                                    SMLoc StartLoc);
   X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc SizeDirLoc,
@@ -1127,18 +1127,24 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
 
   // Try to handle '[' 'Symbol' ']'
   if (getLexer().is(AsmToken::Identifier)) {
-    if (ParseRegister(TmpReg, Start, End)) {
+    SMLoc Loc = Tok.getLoc();
+    if (ParseRegister(TmpReg, Loc, End)) {
       const MCExpr *Disp;
       SMLoc IdentStart = Tok.getLoc();
-      if (getParser().parsePrimaryExpr(Disp, End))
+      if (getParser().parseExpression(Disp, End))
         return 0;
 
       if (X86Operand *Err = ParseIntelVarWithQualifier(Disp, IdentStart))
         return Err;
 
       if (getLexer().isNot(AsmToken::RBrac))
-        return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
+        return ErrorOperand(Tok.getLoc(), "Expected ']' token!");
 
+      if (isParsingInlineAsm()) {
+        // Remove the '[' and ']' from the IR string.
+        InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, Start, 1));
+        InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, Tok.getLoc(), 1));
+      }
       unsigned Len = Tok.getLoc().getPointer() - IdentStart.getPointer();
       StringRef SymName(IdentStart.getPointer(), Len);
       Parser.Lex(); // Eat ']'
@@ -1178,7 +1184,8 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
     }
     case AsmToken::Identifier: {
       // This could be a register or a displacement expression.
-      if(!ParseRegister(TmpReg, Start, End)) {
+      SMLoc Loc = Tok.getLoc();
+      if(!ParseRegister(TmpReg, Loc, End)) {
         SM.onRegister(TmpReg);
         UpdateLocLex = false;
         break;
@@ -1209,6 +1216,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
       Parser.Lex(); // Consume the token.
     }
   }
+  if (isParsingInlineAsm() && Disp && isa<MCSymbolRefExpr>(Disp)) {
+    // Remove the '[' and ']' from the IR string.
+    InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, Start, 1));
+    InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
+  }
 
   if (!Disp)
     Disp = MCConstantExpr::Create(SM.getDisp(), getContext());
@@ -1220,12 +1232,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
     if (ParseIntelDotOperator(Disp, &NewDisp, Err))
       return ErrorOperand(Tok.getLoc(), Err);
     
-    End = Parser.getTok().getEndLoc();
+    End = Tok.getEndLoc();
     Parser.Lex();  // Eat the field.
     Disp = NewDisp;
   }
 
-  StringRef SymName;
   int BaseReg = SM.getBaseReg();
   int IndexReg = SM.getIndexReg();
 
@@ -1298,11 +1309,10 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
 
   // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
   if (getLexer().is(AsmToken::Integer)) {
-    const AsmToken &IntTok = Parser.getTok();
     if (isParsingInlineAsm())
       InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
-                                                  IntTok.getLoc()));
-    uint64_t ImmDisp = IntTok.getIntVal();
+                                                  Tok.getLoc()));
+    uint64_t ImmDisp = Tok.getIntVal();
     Parser.Lex(); // Eat the integer.
     if (getLexer().isNot(AsmToken::LBrac))
       return ErrorOperand(Start, "Expected '[' token!");
@@ -1324,7 +1334,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
 
   const MCExpr *Disp = 0;
   SMLoc IdentStart = Tok.getLoc();
-  if (getParser().parsePrimaryExpr(Disp, End))
+  if (getParser().parseExpression(Disp, End))
     return 0;
 
   if (!isParsingInlineAsm())
@@ -1342,7 +1352,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
                                          const MCExpr **NewDisp,
                                          SmallString<64> &Err) {
-  AsmToken Tok = *&Parser.getTok();
+  const AsmToken &Tok = Parser.getTok();
   uint64_t OrigDispVal, DotDispVal;
 
   // FIXME: Handle non-constant expressions.
@@ -1393,14 +1403,14 @@ bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
 
 /// Parse the 'offset' operator.  This operator is used to specify the
 /// location rather then the content of a variable.
-X86Operand *X86AsmParser::ParseIntelOffsetOfOperator(SMLoc Start) {
-  SMLoc OffsetOfLoc = Start;
+X86Operand *X86AsmParser::ParseIntelOffsetOfOperator() {
+  const AsmToken &Tok = Parser.getTok();
+  SMLoc OffsetOfLoc = Tok.getLoc();
   Parser.Lex(); // Eat offset.
-  Start = Parser.getTok().getLoc();
-  assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
+  assert (Tok.is(AsmToken::Identifier) && "Expected an identifier");
 
-  SMLoc End;
   const MCExpr *Val;
+  SMLoc Start = Tok.getLoc(), End;
   if (getParser().parsePrimaryExpr(Val, End))
     return ErrorOperand(Start, "Unable to parse expression!");
 
@@ -1429,14 +1439,14 @@ enum IntelOperatorKind {
 /// variable.  A variable's size is the product of its LENGTH and TYPE.  The
 /// TYPE operator returns the size of a C or C++ type or variable. If the
 /// variable is an array, TYPE returns the size of a single element.
-X86Operand *X86AsmParser::ParseIntelOperator(SMLoc Start, unsigned OpKind) {
-  SMLoc TypeLoc = Start;
-  Parser.Lex(); // Eat offset.
-  Start = Parser.getTok().getLoc();
-  assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
+X86Operand *X86AsmParser::ParseIntelOperator(unsigned OpKind) {
+  const AsmToken &Tok = Parser.getTok();
+  SMLoc TypeLoc = Tok.getLoc();
+  Parser.Lex(); // Eat operator.
+  assert (Tok.is(AsmToken::Identifier) && "Expected an identifier");
 
-  SMLoc End;
   const MCExpr *Val;
+  SMLoc Start = Tok.getLoc(), End;
   if (getParser().parsePrimaryExpr(Val, End))
     return 0;
 
@@ -1469,19 +1479,20 @@ X86Operand *X86AsmParser::ParseIntelOperator(SMLoc Start, unsigned OpKind) {
 }
 
 X86Operand *X86AsmParser::ParseIntelOperand() {
-  SMLoc Start = Parser.getTok().getLoc(), End;
-  StringRef AsmTokStr = Parser.getTok().getString();
+  const AsmToken &Tok = Parser.getTok();
+  SMLoc Start = Tok.getLoc(), End;
+  StringRef AsmTokStr = Tok.getString();
 
   // Offset, length, type and size operators.
   if (isParsingInlineAsm()) {
     if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
-      return ParseIntelOffsetOfOperator(Start);
+      return ParseIntelOffsetOfOperator();
     if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
-      return ParseIntelOperator(Start, IOK_LENGTH);
+      return ParseIntelOperator(IOK_LENGTH);
     if (AsmTokStr == "size" || AsmTokStr == "SIZE")
-      return ParseIntelOperator(Start, IOK_SIZE);
+      return ParseIntelOperator(IOK_SIZE);
     if (AsmTokStr == "type" || AsmTokStr == "TYPE")
-      return ParseIntelOperator(Start, IOK_TYPE);
+      return ParseIntelOperator(IOK_TYPE);
   }
 
   // Immediate.
@@ -1498,7 +1509,7 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
 
       // Only positive immediates are valid.
       if (!isInteger) {
-        Error(Parser.getTok().getLoc(), "expected a positive immediate "
+        Error(Tok.getLoc(), "expected a positive immediate "
               "displacement before bracketed expr.");
         return 0;
       }