diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -1159,11 +1159,17 @@ `recursion_limit` times, it is an error. If the `recursion_limit` is `None` (the default), no recursive substitution is performed at all. """ - def processLine(ln): + def processLine(ln, ignore_double_percent_substitution=False): # Apply substitutions for a,b in substitutions: if kIsWindows: b = b.replace("\\","\\\\") + + if ignore_double_percent_substitution and a == '#_MARKER_#': + # Defer the %% substitution until the last pass when + # expanding recursively. + continue + # re.compile() has a built-in LRU cache with 512 entries. In some # test suites lit ends up thrashing that cache, which made e.g. # check-llvm run 50% slower. Use an explicit, unbounded cache @@ -1180,16 +1186,20 @@ assert isinstance(recursion_limit, int) and recursion_limit >= 0 origLine = ln steps = 0 - processed = processLine(ln) + processed = processLine(ln, ignore_double_percent_substitution=True) while processed != ln and steps < recursion_limit: ln = processed - processed = processLine(ln) + processed = processLine(ln, ignore_double_percent_substitution=True) steps += 1 if processed != ln: raise ValueError("Recursive substitution of '%s' did not complete " "in the provided recursion limit (%s)" % \ (origLine, recursion_limit)) + + # Finally, if everything's alright, process the line one last time. + # This time we don't ignore the %% substitution. + processed = processLine(ln, ignore_double_percent_substitution=False) return processed diff --git a/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/does-not-substitute-no-limit/test.py b/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/does-not-substitute-no-limit/test.py --- a/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/does-not-substitute-no-limit/test.py +++ b/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/does-not-substitute-no-limit/test.py @@ -1 +1 @@ -# RUN: echo %rec5 +# RUN: echo %rec5 %%s %%%%s diff --git a/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/substitutes-within-limit/test.py b/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/substitutes-within-limit/test.py --- a/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/substitutes-within-limit/test.py +++ b/llvm/utils/lit/tests/Inputs/shtest-recursive-substitution/substitutes-within-limit/test.py @@ -1 +1 @@ -# RUN: echo %rec5 +# RUN: echo %rec5 %%s %%%%s diff --git a/llvm/utils/lit/tests/shtest-recursive-substitution.py b/llvm/utils/lit/tests/shtest-recursive-substitution.py --- a/llvm/utils/lit/tests/shtest-recursive-substitution.py +++ b/llvm/utils/lit/tests/shtest-recursive-substitution.py @@ -3,7 +3,7 @@ # RUN: %{lit} -j 1 %{inputs}/shtest-recursive-substitution/substitutes-within-limit --show-all | FileCheck --check-prefix=CHECK-TEST1 %s # CHECK-TEST1: PASS: substitutes-within-limit :: test.py -# CHECK-TEST1: $ "echo" "STOP" +# CHECK-TEST1: $ "echo" "STOP" "%s" "%%s" # RUN: not %{lit} -j 1 %{inputs}/shtest-recursive-substitution/does-not-substitute-within-limit --show-all | FileCheck --check-prefix=CHECK-TEST2 %s # CHECK-TEST2: UNRESOLVED: does-not-substitute-within-limit :: test.py @@ -11,7 +11,7 @@ # RUN: %{lit} -j 1 %{inputs}/shtest-recursive-substitution/does-not-substitute-no-limit --show-all | FileCheck --check-prefix=CHECK-TEST3 %s # CHECK-TEST3: PASS: does-not-substitute-no-limit :: test.py -# CHECK-TEST3: $ "echo" "%rec4" +# CHECK-TEST3: $ "echo" "%rec4" "%s" "%%s" # RUN: not %{lit} -j 1 %{inputs}/shtest-recursive-substitution/not-an-integer --show-all 2>&1 | FileCheck --check-prefix=CHECK-TEST4 %s # CHECK-TEST4: recursiveExpansionLimit must be either None or an integer