[ms-inline asm] Perform field lookups with the dot operator.
authorChad Rosier <mcrosier@apple.com>
Thu, 25 Oct 2012 21:51:10 +0000 (21:51 +0000)
committerChad Rosier <mcrosier@apple.com>
Thu, 25 Oct 2012 21:51:10 +0000 (21:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166724 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCParser/MCAsmParser.h
lib/Target/X86/AsmParser/X86AsmParser.cpp

index 8a5f37cb0c8cb6efa14eeac2a6cfeb6f19297714..a71d3c321741375d744f30090639a48e5d364a01 100644 (file)
@@ -37,6 +37,8 @@ public:
   virtual ~MCAsmParserSemaCallback(); 
   virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
                                           unsigned &Size) = 0;
+  virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                                    unsigned &Offset) = 0;
 };
 
 /// MCAsmParser - Generic assembler parser interface, for use by target specific
index 00e95596a0a83675d4cd742e2276fa0a12feba67..7f47ef4c63ec2fa6659a9b4b60d8581e5e9760d9 100644 (file)
@@ -841,15 +841,30 @@ bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
     APInt DotDisp;
     DotDispStr.getAsInteger(10, DotDisp);
     DotDispVal = DotDisp.getZExtValue();
+  } else if (Tok.is(AsmToken::Identifier)) {
+    // We should only see an identifier when parsing the original inline asm.
+    // The front-end should rewrite this in terms of immediates.
+    assert (isParsingInlineAsm() && "Unexpected field name!");
+
+    unsigned DotDisp;
+    std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
+    if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
+                                           DotDisp)) {
+      Err = "Unable to lookup field reference!";
+      return true;
+    }
+    DotDispVal = DotDisp;
   } else {
     Err = "Unexpected token type!";
     return true;
   }
 
-  // Special case zero dot displacement.
-  if (!DotDispVal) {
-    *NewDisp = Disp;
-    return false;
+  if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
+    SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
+    unsigned Len = DotDispStr.size();
+    unsigned Val = OrigDispVal + DotDispVal;
+    InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
+                                                Val));
   }
 
   *NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());