mharoush updated this revision to Diff 99778.
mharoush added a comment.

Using identifier info to pass enum information.


Repository:
  rL LLVM

https://reviews.llvm.org/D33278

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

Index: lib/Target/X86/AsmParser/X86AsmParser.cpp
===================================================================
--- lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -718,7 +718,8 @@
   ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
   std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
   bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
-  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
+  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End, 
+                            bool &ReplaceEnumIdentifier);
   std::unique_ptr<X86Operand>
   ParseIntelBracExpression(unsigned SegReg, SMLoc Start, int64_t ImmDisp,
                            bool isSymbol, unsigned Size);
@@ -1306,8 +1307,9 @@
     return false;
   return true;
 }
-
-bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
+bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End, 
+                                        bool &ReplaceEnumIdentifier) {
+  ReplaceEnumIdentifier = false;
   MCAsmParser &Parser = getParser();
   const AsmToken &Tok = Parser.getTok();
 
@@ -1368,11 +1370,40 @@
             PrevTK == AsmToken::RBrac) {
           return false;
       } else {
-        InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
+        InlineAsmIdentifierInfo Info;
+        Info.clear();
         if (ParseIntelIdentifier(Val, Identifier, Info,
                                  /*Unevaluated=*/false, End))
           return true;
-        SM.onIdentifierExpr(Val, Identifier);
+        // Check if the parsed identifier was a constant Integer. Here we 
+        // assume Val is of type MCConstantExpr only when it is safe to replace
+        // the identifier with its constant value.
+        if (const MCConstantExpr *CE = 
+            dyn_cast_or_null<const MCConstantExpr>(Val)) {
+          StringRef ErrMsg;
+          // SM should treat the value as it would an explicit integer in the 
+          // expression.
+          if(SM.onInteger(CE->getValue(), ErrMsg)) 
+            return Error(IdentLoc, ErrMsg);
+          // In case we are called on a bracketed expression,
+          if (isParsingInlineAsm() && SM.getAddImmPrefix()) {
+            // A single rewrite of the integer value is preformed for each enum
+            // identifier. This is only done when we are inside a bracketed 
+            // expression in order to match the behavior for the equivalent 
+            // integer tokens.
+            size_t Len = End.getPointer() - IdentLoc.getPointer();
+            InstInfo->AsmRewrites->emplace_back(AOK_Imm, IdentLoc,Len, 
+                                                CE->getValue());
+            break;
+          }
+          // Set force rewrite flag only when not bracketed expression.
+          ReplaceEnumIdentifier = true;
+        } else {
+          // Notify the SM a variable identifier was found.
+          InlineAsmIdentifierInfo &SMInfo = SM.getIdentifierInfo();
+  	      SMInfo = Info;
+          SM.onIdentifierExpr(Val, Identifier);
+        }
       }
       break;
     }
@@ -1452,7 +1483,8 @@
   // may have already parsed an immediate displacement before the bracketed
   // expression.
   IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
-  if (ParseIntelExpression(SM, End))
+  bool ReplaceEnumIdentifier;
+  if (ParseIntelExpression(SM, End, ReplaceEnumIdentifier))
     return nullptr;
 
   const MCExpr *Disp = nullptr;
@@ -1559,7 +1591,15 @@
   // failed parsing.
   assert((End.getPointer() == EndPtr || !Result) &&
          "frontend claimed part of a token?");
-
+  
+  // Check if the search yielded a constant integer (enum identifier).
+  if (Result && Info.IsConstEnum) {
+    // By creating MCConstantExpr we let the user of Val know it is safe
+    // to use as an explicit constant with value = ConstVal.
+    Val = MCConstantExpr::create(Info.ConstIntValue.getSExtValue(), 
+                                 getParser().getContext());
+    return false;
+  }
   // If the identifier lookup was unsuccessful, assume that we are dealing with
   // a label.
   if (!Result) {
@@ -1852,18 +1892,21 @@
   AsmToken StartTok = Tok;
   IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
                            /*AddImmPrefix=*/false);
-  if (ParseIntelExpression(SM, End))
+  // The parsed expression may contain enum identifier tokens which we must 
+  // replace, ReplaceEnumIdentifier flag lets us know when to force rewrite.
+  bool ReplaceEnumIdentifier;
+  if (ParseIntelExpression(SM, End, ReplaceEnumIdentifier))
     return nullptr;
-
   bool isSymbol = SM.getSym() && SM.getSym()->getKind() != MCExpr::Constant;
   int64_t Imm = SM.getImm();
   if (SM.getSym() && SM.getSym()->getKind() == MCExpr::Constant)
     SM.getSym()->evaluateAsAbsolute(Imm);
 
-  if (StartTok.isNot(AsmToken::Identifier) &&
+  if ((ReplaceEnumIdentifier ||
+      StartTok.isNot(AsmToken::Identifier)) &&
       StartTok.isNot(AsmToken::String) && isParsingInlineAsm()) {
     unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
-    if (StartTok.getString().size() == Len)
+    if (StartTok.getString().size() == Len && !ReplaceEnumIdentifier)
       // Just add a prefix if this wasn't a complex immediate expression.
       InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
     else
Index: include/llvm/MC/MCParser/MCAsmParser.h
===================================================================
--- include/llvm/MC/MCParser/MCAsmParser.h
+++ include/llvm/MC/MCParser/MCAsmParser.h
@@ -39,13 +39,17 @@
   void *OpDecl;
   bool IsVarDecl;
   unsigned Length, Size, Type;
-
+  bool IsConstEnum;
+  APInt ConstIntValue;
   void clear() {
     OpDecl = nullptr;
     IsVarDecl = false;
     Length = 1;
     Size = 0;
     Type = 0;
+    IsConstEnum = false;
+    // On clear flush possibly old APInt value as a precaution;
+    ConstIntValue = APInt();
   }
 };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to