[llvm] 35828b8 - [ms] [llvm-ml] Implement the expression expansion operator

Eric Astor via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 25 13:11:19 PST 2020


Author: Eric Astor
Date: 2020-11-25T16:11:00-05:00
New Revision: 35828b84a5232df020d6de250c3c268e2ccaaf11

URL: https://github.com/llvm/llvm-project/commit/35828b84a5232df020d6de250c3c268e2ccaaf11
DIFF: https://github.com/llvm/llvm-project/commit/35828b84a5232df020d6de250c3c268e2ccaaf11.diff

LOG: [ms] [llvm-ml] Implement the expression expansion operator

In text-item contexts, %expr expands to a string containing the results of evaluating `expr`.

Reviewed By: thakis

Differential Revision: https://reviews.llvm.org/D89736

Added: 
    

Modified: 
    llvm/lib/MC/MCParser/MasmParser.cpp
    llvm/test/tools/llvm-ml/macro_function.test

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index 9b63148c6860..8b5d4b85a58b 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -912,7 +912,8 @@ class MasmParser : public MCAsmParser {
 
   // macro directives
   bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
-  bool parseDirectiveExitMacro(StringRef Directive, std::string &Value);
+  bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,
+                               std::string &Value);
   bool parseDirectiveEndMacro(StringRef Directive);
   bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);
 
@@ -2307,7 +2308,7 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
       return parseDirectiveCFIWindowSave();
     case DK_EXITM:
       Info.ExitValue = "";
-      return parseDirectiveExitMacro(IDVal, *Info.ExitValue);
+      return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);
     case DK_ENDM:
       Info.ExitValue = "";
       return parseDirectiveEndMacro(IDVal);
@@ -3207,7 +3208,7 @@ bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
       // Accept a text-list, not just one text-item.
       auto parseItem = [&]() -> bool {
         if (parseTextItem(Value))
-          return true;
+          return TokError("expected text item");
         Var.TextValue += Value;
         return false;
       };
@@ -3283,8 +3284,38 @@ bool MasmParser::parseAngleBracketString(std::string &Data) {
 
 /// textItem ::= textLiteral | textMacroID | % constExpr
 bool MasmParser::parseTextItem(std::string &Data) {
-  // TODO(epastor): Support textMacroID and % expansion of expressions.
-  return parseAngleBracketString(Data);
+  switch (getTok().getKind()) {
+  default:
+    return true;
+  case AsmToken::Percent: {
+    int64_t Res;
+    if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))
+      return true;
+    Data = std::to_string(Res);
+    return false;
+  }
+  case AsmToken::Less:
+  case AsmToken::LessEqual:
+  case AsmToken::LessLess:
+  case AsmToken::LessGreater:
+    return parseAngleBracketString(Data);
+  case AsmToken::Identifier: {
+    StringRef ID;
+    if (parseIdentifier(ID))
+      return true;
+
+    auto it = Variables.find(ID);
+    if (it == Variables.end())
+      return true;
+
+    const Variable &Var = it->second;
+    if (!Var.IsText)
+      return true;
+    Data = Var.TextValue;
+    return false;
+  }
+  }
+  llvm_unreachable("unhandled token kind");
 }
 
 /// parseDirectiveAscii:
@@ -5503,11 +5534,13 @@ bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
 
 /// parseDirectiveExitMacro
 /// ::= "exitm" [textitem]
-bool MasmParser::parseDirectiveExitMacro(StringRef Directive,
+bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
+                                         StringRef Directive,
                                          std::string &Value) {
-  if (getTok().isNot(AsmToken::EndOfStatement)) {
-    parseTextItem(Value);
-  }
+  SMLoc EndLoc = getTok().getLoc();
+  if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value))
+    return Error(EndLoc,
+                 "unable to parse text item in '" + Directive + "' directive");
   eatToEndOfStatement();
 
   if (!isInsideMacroInstantiation())
@@ -5740,7 +5773,7 @@ bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
 }
 
 /// parseDirectiveIfb
-/// ::= .ifb string
+/// ::= .ifb textitem
 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
   TheCondStack.push_back(TheCondState);
   TheCondState.TheCond = AsmCond::IfCond;
@@ -5750,7 +5783,7 @@ bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
   } else {
     std::string Str;
     if (parseTextItem(Str))
-      return TokError("expected string parameter for 'ifb' directive");
+      return TokError("expected text item parameter for 'ifb' directive");
 
     if (parseToken(AsmToken::EndOfStatement,
                    "unexpected token in 'ifb' directive"))
@@ -5764,14 +5797,15 @@ bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
 }
 
 /// parseDirectiveIfidn
-///   ::= ifidn string1, string2
-bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, bool CaseInsensitive) {
+///   ::= ifidn textitem, textitem
+bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
+                                     bool CaseInsensitive) {
   std::string String1, String2;
 
   if (parseTextItem(String1)) {
     if (ExpectEqual)
-      return TokError("expected string parameter for 'ifidn' directive");
-    return TokError("expected string parameter for 'ifdif' directive");
+      return TokError("expected text item parameter for 'ifidn' directive");
+    return TokError("expected text item parameter for 'ifdif' directive");
   }
 
   if (Lexer.isNot(AsmToken::Comma)) {
@@ -5784,8 +5818,8 @@ bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, bool
 
   if (parseTextItem(String2)) {
     if (ExpectEqual)
-      return TokError("expected string parameter for 'ifidn' directive");
-    return TokError("expected string parameter for 'ifdif' directive");
+      return TokError("expected text item parameter for 'ifidn' directive");
+    return TokError("expected text item parameter for 'ifdif' directive");
   }
 
   TheCondStack.push_back(TheCondState);
@@ -5879,7 +5913,7 @@ bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
 }
 
 /// parseDirectiveElseIfb
-/// ::= elseifb expression
+/// ::= elseifb textitem
 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
   if (TheCondState.TheCond != AsmCond::IfCond &&
       TheCondState.TheCond != AsmCond::ElseIfCond)
@@ -5895,8 +5929,11 @@ bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
     eatToEndOfStatement();
   } else {
     std::string Str;
-    if (parseTextItem(Str))
-      return TokError("expected string parameter for 'elseifb' directive");
+    if (parseTextItem(Str)) {
+      if (ExpectBlank)
+        return TokError("expected text item parameter for 'elseifb' directive");
+      return TokError("expected text item parameter for 'elseifnb' directive");
+    }
 
     if (parseToken(AsmToken::EndOfStatement,
                    "unexpected token in 'elseifb' directive"))
@@ -5956,7 +5993,7 @@ bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
 }
 
 /// parseDirectiveElseIfidn
-/// ::= elseifidn string1, string2
+/// ::= elseifidn textitem, textitem
 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
                                          bool CaseInsensitive) {
   if (TheCondState.TheCond != AsmCond::IfCond &&
@@ -5976,8 +6013,9 @@ bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
 
     if (parseTextItem(String1)) {
       if (ExpectEqual)
-        return TokError("expected string parameter for 'elseifidn' directive");
-      return TokError("expected string parameter for 'elseifdif' directive");
+        return TokError(
+            "expected text item parameter for 'elseifidn' directive");
+      return TokError("expected text item parameter for 'elseifdif' directive");
     }
 
     if (Lexer.isNot(AsmToken::Comma)) {
@@ -5991,8 +6029,9 @@ bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
 
     if (parseTextItem(String2)) {
       if (ExpectEqual)
-        return TokError("expected string parameter for 'elseifidn' directive");
-      return TokError("expected string parameter for 'elseifdif' directive");
+        return TokError(
+            "expected text item parameter for 'elseifidn' directive");
+      return TokError("expected text item parameter for 'elseifdif' directive");
     }
 
     if (CaseInsensitive)
@@ -6130,7 +6169,7 @@ bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
 }
 
 /// parseDirectiveErrorIfidn
-///   ::= .erridn textitem1, textitem2[, message]
+///   ::= .erridn textitem, textitem[, message]
 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
                                           bool CaseInsensitive) {
   if (!TheCondStack.empty()) {

diff  --git a/llvm/test/tools/llvm-ml/macro_function.test b/llvm/test/tools/llvm-ml/macro_function.test
index 135bdeb1eede..98b3f25aabc8 100644
--- a/llvm/test/tools/llvm-ml/macro_function.test
+++ b/llvm/test/tools/llvm-ml/macro_function.test
@@ -73,25 +73,34 @@ factorial2 MACRO n
   ENDIF
 ENDM
 
+string_recursive_test PROC
+; CHECK-LABEL: string_recursive_test:
+
+  mov eax, factorial(5)
+; CHECK: mov eax, 120
+  mov eax, factorial2(4)
+; CHECK: mov eax, 24
+  mov eax, 11 + factorial(6) - 11
+; CHECK: mov eax, 720
+
+  ret
+string_recursive_test ENDP
+
 fibonacci MACRO n
   IF n LE 2
-    EXITM <(1)>
+    EXITM %1
   ELSE
-    EXITM <(fibonacci(n-1)+fibonacci(n-2))>
+    EXITM %fibonacci(n-1)+fibonacci(n-2)
   ENDIF
 ENDM
 
-recursive_test PROC
-; CHECK-LABEL: recursive_test:
+expr_recursive_test PROC
+; CHECK-LABEL: expr_recursive_test:
 
-  mov eax, factorial(5)
-; CHECK: mov eax, 120
-  mov eax, factorial2(4)
-; CHECK: mov eax, 24
-  mov eax, 11 + fibonacci(7) - 11
-; CHECK: mov eax, 13
+  mov eax, fibonacci(10)
+; CHECK: mov eax, 55
 
   ret
-recursive_test ENDP
+expr_recursive_test ENDP
 
 end


        


More information about the llvm-commits mailing list