make XFAIL, REQUIRES, and UNSUPPORTED support multi-line expressions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351668 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py
index 4d903b4..2e885b4 100644
--- a/utils/lit/lit/TestRunner.py
+++ b/utils/lit/lit/TestRunner.py
@@ -1401,13 +1401,17 @@
     @staticmethod
     def _handleBooleanExpr(line_number, line, output):
         """A parser for BOOLEAN_EXPR type keywords"""
+        parts = [s.strip() for s in line.split(',') if s.strip() != '']
+        if output and output[-1][-1] == '\\':
+            output[-1] = output[-1][:-1] + parts[0]
+            del parts[0]
         if output is None:
             output = []
-        output.extend([s.strip() for s in line.split(',')])
+        output.extend(parts)
         # Evaluate each expression to verify syntax.
         # We don't want any results, just the raised ValueError.
         for s in output:
-            if s != '*':
+            if s != '*' and not s.endswith('\\'):
                 BooleanExpression.evaluate(s, [])
         return output
 
@@ -1486,6 +1490,15 @@
         return lit.Test.Result(Test.UNRESOLVED,
                                "Test has unterminated run lines (with '\\')")
 
+    # Check boolean expressions for unterminated lines.
+    for key in keyword_parsers:
+        kp = keyword_parsers[key]
+        if kp.kind != ParserKind.BOOLEAN_EXPR:
+            continue
+        value = kp.getValue()
+        if value and value[-1][-1] == '\\':
+            raise ValueError("Test has unterminated %s lines (with '\\')" % key)
+
     # Enforce REQUIRES:
     missing_required_features = test.getMissingRequiredFeatures()
     if missing_required_features:
diff --git a/utils/lit/tests/Inputs/testrunner-custom-parsers/test.txt b/utils/lit/tests/Inputs/testrunner-custom-parsers/test.txt
index ed118f3..e280603 100644
--- a/utils/lit/tests/Inputs/testrunner-custom-parsers/test.txt
+++ b/utils/lit/tests/Inputs/testrunner-custom-parsers/test.txt
@@ -9,5 +9,11 @@
 //
 // MY_CUSTOM: a b c
 //
+// MY_BOOL: a && (\
+// MY_BOOL: b)
+// MY_BOOL: d
+//
+// MY_BOOL_UNTERMINATED: a \
+//
 // END.
 // MY_LIST: five
diff --git a/utils/lit/tests/unit/TestRunner.py b/utils/lit/tests/unit/TestRunner.py
index 89209d8..a9cfd86 100644
--- a/utils/lit/tests/unit/TestRunner.py
+++ b/utils/lit/tests/unit/TestRunner.py
@@ -9,6 +9,7 @@
 import tempfile
 
 import lit
+import lit.Test as Test
 from lit.TestRunner import ParserKind, IntegratedTestKeywordParser, \
                            parseIntegratedTestScript
 
@@ -57,9 +58,11 @@
             IntegratedTestKeywordParser("MY_TAG.", ParserKind.TAG),
             IntegratedTestKeywordParser("MY_DNE_TAG.", ParserKind.TAG),
             IntegratedTestKeywordParser("MY_LIST:", ParserKind.LIST),
+            IntegratedTestKeywordParser("MY_BOOL:", ParserKind.BOOLEAN_EXPR),
             IntegratedTestKeywordParser("MY_RUN:", ParserKind.COMMAND),
             IntegratedTestKeywordParser("MY_CUSTOM:", ParserKind.CUSTOM,
-                                        custom_parse)
+                                        custom_parse),
+
         ]
 
     @staticmethod
@@ -102,6 +105,25 @@
         self.assertEqual(value[0].strip(), "%dbg(MY_RUN: at line 4)  baz")
         self.assertEqual(value[1].strip(), "%dbg(MY_RUN: at line 7)  foo  bar")
 
+    def test_boolean(self):
+        parsers = self.make_parsers()
+        self.parse_test(parsers)
+        bool_parser = self.get_parser(parsers, 'MY_BOOL:')
+        value = bool_parser.getValue()
+        self.assertEqual(len(value), 2)  # there are only two run lines
+        self.assertEqual(value[0].strip(), "a && (b)")
+        self.assertEqual(value[1].strip(), "d")
+
+    def test_boolean_unterminated(self):
+        parsers = self.make_parsers() + \
+            [IntegratedTestKeywordParser("MY_BOOL_UNTERMINATED:", ParserKind.BOOLEAN_EXPR)]
+        try:
+            self.parse_test(parsers)
+            self.fail('expected exception')
+        except ValueError as e:
+            self.assertIn("Test has unterminated MY_BOOL_UNTERMINATED: lines", str(e))
+
+
     def test_custom(self):
         parsers = self.make_parsers()
         self.parse_test(parsers)