Index: llvm/docs/TestingGuide.rst =================================================================== --- llvm/docs/TestingGuide.rst +++ llvm/docs/TestingGuide.rst @@ -814,6 +814,176 @@ continuation can be continued in the same manner. A continuation containing only whitespace after its ``:`` is an error. +**Function substitutions:** + +In the example from the previous section, notice that there are two dimensions +being tested: the triple, and whether OpenMP simd mode is enabled. The test +would be easier to read and maintain if the iteration over one of those +dimensions, say the triple, were encapsulated in another substitution, say +``%{check-triples}``, to be used at each point along the other dimension. +However, there is no way to place ``DEFINE:`` or ``REDEFINE:`` directives in the +value of a substitution, so how can ``%{check-triples}`` set the triple before +each of its uses of ``%{check}``? + +Lit supports function substitutions to address this use case. That is, if we +define ``%{check}`` as a function substitution that takes the triple as an +argument, ``%{check-triples}`` can then use it once for each triple. Unless we +are using ``recursiveExpansionLimit``, we must be careful to define ``%{check}`` +before ``%{check-triples}`` in order for both to expand as expected: + +.. code-block:: llvm + + ; DEFINE: %{cflags} = + ; DEFINE: %{fcflags} = + + ; DEFINE: %{check}( TRIPLE %) = \ + ; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{cflags} \ + ; DEFINE: -triple %{TRIPLE} -emit-llvm -o - %s | \ + ; DEFINE: FileCheck %{fcflags} %s + + ; DEFINE: %{check-triples} = \ + ; DEFINE: %{check}( x86_64-apple-darwin10.6.0 %) && \ + ; DEFINE: %{check}( x86_64-unknown-linux-gnu %) + + ; REDEFINE: %{cflags} = -fopenmp-simd + ; REDEFINE: %{fcflags} = -check-prefix=SIMD + ; RUN: %{check-triples} + + ; REDEFINE: %{cflags} = + ; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD + ; RUN: %{check-triples} + +Notice that ``%{check}`` has two kinds of parameters now: ``%{TRIPLE}`` is now a +function parameter, but ``%{cflags}`` and ``%{fcflags}`` are still standalone +parameter substitutions that must be initially defined before ``%{check}`` +unless we are using ``recursiveExpansionLimit``. + +Because function substitutions are usually more composable, you might decide +that any parameterized substitution is best written as a function substitution. +For example, ``%{check-triples}`` above could be converted to a function +substitution as well: + +.. code-block:: llvm + + ; DEFINE: %{check}( TRIPLE %, CFLAGS %, FCFLAGS %) = \ + ; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{CFLAGS} \ + ; DEFINE: -triple %{TRIPLE} -emit-llvm -o - %s | \ + ; DEFINE: FileCheck %{FCFLAGS} %s + + ; DEFINE: %{check-triples}( CFLAGS %, FCFLAGS %) = \ + ; DEFINE: %{check}( x86_64-apple-darwin10.6.0 %, %{CFLAGS} %, %{FCFLAGS} %) && \ + ; DEFINE: %{check}( x86_64-unknown-linux-gnu %, %{CFLAGS} %, %{FCFLAGS} %) + + ; RUN: %{check-triples}( -fopenmp-simd %, -check-prefix=SIMD %) + ; RUN: %{check-triples}( %, -check-prefix=NO-SIMD %) + +For a complex substitution with a long list of parameters, it is +sometimes more readable if at least some of its parameters remain as +standalone substitutions. As in the original example from the +previous section, actual arguments are then optional, and they are +recognized by their formal parameter names instead of by their +positions in a long sequence of actual arguments. + +If you end up with too many levels of substitutions, debugging test +failures can be challenging because the only location information lit +reports in the test output is for the ``RUN:`` line. ``%(line)`` +substitutions can improve this scenario. For example, because +``%(line)`` expands immediately within a ``DEFINE:``, ``REDEFINE:``, +or ``RUN:`` directive, it can be used to gather location information +at every level of the expansion, and that information can then be +reported with a command like ``echo``: + +.. code-block:: llvm + + ; DEFINE: %{check}( LOC %, TRIPLE %, CFLAGS %, FCFLAGS %) = \ + ; DEFINE: echo 'At test lines %{LOC}, %(line)' && \ + ; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{CFLAGS} \ + ; DEFINE: -triple %{TRIPLE} -emit-llvm -o - %s | \ + ; DEFINE: FileCheck %{FCFLAGS} %s + + ; DEFINE: %{check-triples}( LOC %, CFLAGS %, FCFLAGS %) = \ + ; DEFINE: %{check}( %{LOC}, %(line) %, x86_64-apple-darwin10.6.0 %, %{CFLAGS} %, %{FCFLAGS} %) && \ + ; DEFINE: %{check}( %{LOC}, %(line) %, x86_64-unknown-linux-gnu %, %{CFLAGS} %, %{FCFLAGS} %) + + ; RUN: %{check-triples}( %(line) %, -fopenmp-simd %, -check-prefix=SIMD %) + ; RUN: %{check-triples}( %(line) %, %, -check-prefix=NO-SIMD %) + +If your test suite is configured to use lit's internal shell, you can +portably replace ``echo`` with the ``:`` command so that the location +information is reported only when lit prints the command and not again +when lit executes the command. + +As a modification of the rules presented in the previous section for +``DEFINE:`` and ``REDEFINE:`` directives, the following properties +apply in the case of function substitutions: + +- **Structural syntax**: In the directive, ``%{name}`` must be followed + immediately by ``(`` without intervening whitespace. That is, ``%{name}(`` is + a single token. The same is true in uses of the substitution. Formal + parameter names in the directive appear after ``%{name}(`` and must be + separated by ``%,`` and terminated by ``%)``. The same is true for actual + arguments in uses. In the directive, there must be at least one formal + parameter. If either ``%,`` or ``%)`` must occur in an actual argument, it + can be escaped as ``%%,`` or ``%%)``. However, ``,`` and ``)`` need not be + otherwise escaped. For example, an actual argument can easily contain a + comma-delimited list of FileCheck prefixes, or it can contain parenthesized + expressions. +- **Parameter names**: Each parameter name must be one or more alphanumeric + characters and underscores not starting with a digit. Parameter names do not + have the same set of constraints as substitution names because parameter names + must be valid python identifiers in order to be used in the substitution's + pattern. In the formal parameter list in the directive, parameters are + spelled without the enclosing ``%{`` and ``}`` for the sake of conciseness and + readability. However, they must include those when referenced in the + substitution's value. +- **Whitespace**: In the directive, whitespace before the ``%{name}(`` and + between the ``%)`` and ``=`` is optional and discarded. Leading and trailing + whitespace around a formal parameter name in the directive or around an actual + argument in a use is optional and discarded. If only whitespace is provided + for an actual argument, the argument is the empty string. This behavior + facilitates formatting parameter lists and argument lists for readability. +- **Line continuations**: Line continuations are permitted in both formal + parameter lists and actual argument lists. This is because the text in a + ``RUN:``, ``DEFINE:``, or ``REDEFINE:`` directive is not parsed until all line + continuations have been appended. +- **Invalid syntax**: Lit diagnoses invalid parameter list syntax in the + directive. However, lit does not diagnose invalid actual argument list syntax + in uses. Instead, if the syntax for a use is not followed, the substitution's + pattern simply does not match, and so the substitution does not expand, just + like any other substitution. +- **Required actual arguments**: All arguments must appear in a use, or the + substitution does not expand. This behavior facilitates debugging expansions + by making it clear which substitution needs to be investigated. In contrast, + imagine the behavior if trailing arguments were optional and you accidentally + type ``,`` instead of ``%,``. All remaining actual arguments would map to the + wrong formal parameters, and the only clue as to the problem would likely be a + corrupt ``RUN:`` line. +- **Substitution name conflicts**: As discussed in the previous section, + ``DEFINE:`` and ``REDEFINE:`` are careful to make sure ``%{name}`` doesn't + appear in any other substitution's pattern. For function substitutions, the + parameter list is not included in this check. That is, the ``%{name}`` alone + is enough to create a conflict. As a result, overloading functions is not + possible. This restriction facilitates debugging in the same way as requiring + all arguments. +- **Parameter name conflicts**: When ``REDEFINE:`` searches the substitution + list for the substitution to actually redefine, it does check the parameters. + It will fail even if a parameter name changes. That is, the parameter names + are part of the substitution's pattern, and the pattern must be identical. +- **Function substitution use in argument**: A use of a function substitution, + such as ``%{outer}``, will initially fail to expand if an argument contains + text, such as ``%{inner}(``, that lexically looks like the start of a function + substitution use. The problem is python's ``re`` package is not powerful + enough to balance parentheses in a single pattern match. Thus, a function + substitution's pattern is designed to require the use of ``%{inner}`` to + expand first, and then the use of ``%{outer}`` can expand later, achieving + parentheses balancing via multiple pattern matches. However, by default, this + means the ``DEFINE:`` directive order must be ``%{outer}`` before + ``%{inner}``. That might be hard to remember, so it is probably best to use + ``recursiveExpansionLimit`` if you plan to use one function substitution in + the argument of another. A more powerful regular expression engine for python + that is capable of recursion appears to be in development, so this limitation + might one day be eliminated. + Options ------- Index: llvm/utils/lit/lit/TestRunner.py =================================================================== --- llvm/utils/lit/lit/TestRunner.py +++ llvm/utils/lit/lit/TestRunner.py @@ -1298,6 +1298,8 @@ continuation lines. name: The substitution's name, or None if more continuation lines are still required. + params: The substitution's parameter name list, or None if more continuation + lines are still required. value: The substitution's value, or None if more continuation lines are still required. """ @@ -1306,6 +1308,7 @@ super().__init__(start_line_number, end_line_number, keyword) self.body = line self.name = None + self.params = None self.value = None self._parse_body() @@ -1329,8 +1332,8 @@ def _parse_body(self): """ If no more line continuations are required, parse all the directive's - accumulated lines in order to identify the substitution's name and full - value, and raise an exception if invalid. + accumulated lines in order to identify the substitution's name, any + parameters, and value, and raise an exception if invalid. """ if self.needs_continuation(): return @@ -1340,7 +1343,7 @@ parts = self.body.split('=', 1) if len(parts) == 1: raise ValueError("Substitution's definition does not contain '='") - self.name = parts[0].strip() + lhs = parts[0].strip() self.value = parts[1].strip() # Check the substitution's name. @@ -1358,12 +1361,47 @@ # # Actually, '{' and '}' are special if they contain only digits possibly # separated by a comma. Requiring a leading letter avoids that. - if not re.fullmatch(r'%{[_a-zA-Z][-_:0-9a-zA-Z]*}', self.name): + name_match = re.match(r'^%{[_a-zA-Z][-_:0-9a-zA-Z]*}', lhs) + if not name_match: raise ValueError( - f"Substitution name '{self.name}' is malformed as it must " - f"start with '%{{', it must end with '}}', and the rest must " - f"start with a letter or underscore and contain only " - f"alphanumeric characters, hyphens, underscores, and colons") + f"Substitution name '{lhs}' is malformed as it must start with " + f"'%{{', it must end with '}}', and the rest must start with a " + f"letter or underscore and contain only alphanumeric " + f"characters, hyphens, underscores, and colons") + self.name = name_match.group(0) + param_list = lhs[name_match.end():] + + # Parse any parameter list. + if not param_list: + return + if param_list[0] != '(': + raise ValueError( + f"Substitution name '{self.name}' must be followed by '=' " + f"(possibly with intervening whitespace) or by '(' (without " + f"intervening whitespace)") + if param_list[-2:] != '%)': + raise ValueError(f"Parameter list of substitution '{self.name}' " + f"must end with '%)'") + self.params = param_list[1:-2].strip() + if not self.params: + raise ValueError( + f"Substitution '{self.name}' must be defined with no parameter " + f"list or at least one parameter") + self.params = self.params.split('%,') + for i, param in enumerate(self.params): + self.params[i] = param = param.strip() + notes = '' + # Parameter names must be valid python identifiers so we can use + # '(?P...)' to match them. + if not re.fullmatch('[_a-zA-Z][_0-9a-zA-Z]*', param): + if re.search('[,\s]', param): + notes += "\nParameter names must be separated by '%,'" + raise ValueError( + f"Parameter {i+1} of substitution '{self.name}' is " + f"malformed as it must be one or more alphanumeric " + f"characters and underscores not starting with a digit\n" + f"Parameter {i+1} is: {param}" + f"{notes}") def adjust_substitutions(self, substitutions): """ @@ -1371,7 +1409,55 @@ """ assert not self.needs_continuation(), \ "expected directive continuations to be parsed before applying" + call_re = self.name value_repl = self.value.replace('\\', '\\\\') + if self.params: + params_re = '' + for param in self.params: + # Trailing empty actual arguments are *not* optional for a + # reason. Imagine the behavior if they were optional and you + # accidentally typed ',' instead of '%,'. That and the next + # intended actual argument would become part of the previous + # actual argument, and any additional actual arguments would map + # to the wrong formal parameters. The result would be a + # confusing expansion. However, because actual arguments are + # not optional, the effect instead is that the substitution + # doesn't expand, making it clearer that you simply botched the + # substitution syntax (or the expansion order is insufficient). + # The minor inconvenience of extra '%,' seems worth the improved + # debugability. + # + # Don't expand the substitution if an argument contains a call + # to another function-like substitution. The problem is + # python's re is not powerful enough to balance parentheses, so + # we have no way to prevent the outer call from terminating at + # the end of the inner call or vice-versa. Instead, we just + # prevent arguments from containing either the start or end of a + # call, and thus the inner call must expand first. Substitution + # order or recursiveExpansionLimit might have to be adjusted in + # order for the outer call to then expand. + if params_re: + params_re += '%,' + params_re += '\s*' # trim leading ws to facilitate formatting + params_re += '(?!\s)' # can't be followed by ws, or might have + # catastrophic backtracking + params_re += '(?P<' + param + '>' # start actual arg + params_re += '(?:' + params_re += '(?:' + params_re += '[^%]' # char that doesn't start an escape + params_re += '|%[^{,)]' # escape not special in arg list + params_re += '|%{(?![^}]+}\()' # '%{' but not '%{...}(' + params_re += ')+' # require non-empty arg + params_re += '(?') + call_re += '\(' + params_re + '%\)' existing = [i for i, subst in enumerate(substitutions) if self.name in subst[0]] existing_res = ''.join("\nExisting pattern: " + substitutions[i][0] @@ -1383,7 +1469,7 @@ f"already defined before '{self.keyword}' directive " f"{self.get_location()}" f"{existing_res}") - substitutions.insert(0, (self.name, value_repl)) + substitutions.insert(0, (call_re, value_repl)) return assert self.keyword == 'REDEFINE:' if len(existing) > 1: @@ -1396,14 +1482,14 @@ raise ValueError( f"No substitution for '{self.name}' is defined before " f"'{self.keyword}' directive {self.get_location()}") - if substitutions[existing[0]][0] != self.name: + if substitutions[existing[0]][0] != call_re: raise ValueError( f"Existing substitution whose pattern contains '{self.name}' " f"does not have the pattern specified by '{self.keyword}' " f"directive {self.get_location()}\n" - f"Expected pattern: {self.name}" + f"Expected pattern: {call_re}" f"{existing_res}") - substitutions[existing[0]] = (self.name, value_repl) + substitutions[existing[0]] = (call_re, value_repl) def applySubstitutions(script, substitutions, conditions={}, Index: llvm/utils/lit/tests/Inputs/shtest-define/actual-arg-catastrophic-backtracking.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/actual-arg-catastrophic-backtracking.txt @@ -0,0 +1,65 @@ +# Make sure two few arguments don't lead to catastrophic backtracking in +# python's regex engine. This can occur because it's tempting to write the +# regex for an actual argument and its leading/trailing whitespace as +# '\s*(?P...)\s*' where '...' is a regex that accepts any series of +# leading/trailing whitespace as well. +# +# No substitution expansion should actually occur because there are two few +# arguments. White space is collapsed in CHECK directives here just because +# we're not using FileCheck's -strict-whitespace. + +# DEFINE: %{f}(A%, B%, C%, D%, E%) = hello world + +# Check when each arg is only whitespace. +# +# RUN: echo '%{f}(\ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: %, \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: %, \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: %, \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: \ +# RUN: %)' +# +# CHECK: %{f}( %, %, %, %) + +# Check when each arg has non-whitespace with leading and trailing whitespace. +# +# RUN: echo '%{f}(\ +# RUN: \ +# RUN: \ +# RUN: a \ +# RUN: \ +# RUN: %, \ +# RUN: \ +# RUN: \ +# RUN: b \ +# RUN: \ +# RUN: %, \ +# RUN: \ +# RUN: \ +# RUN: c \ +# RUN: \ +# RUN: %, \ +# RUN: \ +# RUN: \ +# RUN: d \ +# RUN: \ +# RUN: %)' +# +# CHECK: %{f}( a %, b %, c %, d %) + +# CHECK: Passed: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/actual-arg-count.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/actual-arg-count.txt @@ -0,0 +1,84 @@ +# Check that expansion only happens with the correct number of actual arguments +# and that empty arguments are fine. + +# DEFINE: %{f1}( p0 %) = f1('%{p0}') +# DEFINE: %{f2}( p0 %, p1 %) = f2('%{p0}', '%{p1}') +# DEFINE: %{f3}( p0 %, p1 %, p2 %) = f3('%{p0}', '%{p1}', '%{p2}') + +# RUN: echo "%{f1}(%)" +# RUN: echo "%{f1}(f%)" +# RUN: echo "%{f1}(fgh%)" +# RUN: echo "%{f1}(%,)" +# RUN: echo "%{f1}(f%,)" +# RUN: echo "%{f1}(f%,g)" +# RUN: echo "%{f1}(f%,g%,h)" +# CHECK: f1('') +# CHECK: f1('f') +# CHECK: f1('fgh') +# CHECK: %{f1}(%,) +# CHECK: %{f1}(f%,) +# CHECK: %{f1}(f%,g) +# CHECK: %{f1}(f%,g%,h) + +# RUN: echo "%{f2}(%)" +# RUN: echo "%{f2}(f%)" +# RUN: echo "%{f2}(%,%)" +# RUN: echo "%{f2}(f%,%)" +# RUN: echo "%{f2}(%,g%)" +# RUN: echo "%{f2}(f%,g%)" +# RUN: echo "%{f2}(fgh%,ghi%)" +# RUN: echo "%{f2}(%,%,%)" +# RUN: echo "%{f2}(f%,%,%)" +# RUN: echo "%{f2}(f%,g%,%)" +# RUN: echo "%{f2}(f%,g%,h%)" +# RUN: echo "%{f2}(f%,g%,h%,i%)" +# CHECK: %{f2}(%) +# CHECK: %{f2}(f%) +# CHECK: f2('', '') +# CHECK: f2('f', '') +# CHECK: f2('', 'g') +# CHECK: f2('f', 'g') +# CHECK: f2('fgh', 'ghi') +# CHECK: %{f2}(%,%,%) +# CHECK: %{f2}(f%,%,%) +# CHECK: %{f2}(f%,g%,%) +# CHECK: %{f2}(f%,g%,h%) +# CHECK: %{f2}(f%,g%,h%,i%) + +# RUN: echo "%{f3}(%)" +# RUN: echo "%{f3}(%,%)" +# RUN: echo "%{f3}(f%,g%)" +# RUN: echo "%{f3}(%,%,%)" +# RUN: echo "%{f3}(%,%,%)" +# RUN: echo "%{f3}(f%,%,%)" +# RUN: echo "%{f3}(%,g%,%)" +# RUN: echo "%{f3}(%,%,h%)" +# RUN: echo "%{f3}(f%,g%,%)" +# RUN: echo "%{f3}(f%,%,h%)" +# RUN: echo "%{f3}(%,g%,h%)" +# RUN: echo "%{f3}(f%,g%,h%)" +# RUN: echo "%{f3}(fgh%,ghi%,hij%)" +# RUN: echo "%{f3}(%,%,%,%)" +# RUN: echo "%{f3}(f%,%,%,%)" +# RUN: echo "%{f3}(f%,g%,%,%)" +# RUN: echo "%{f3}(f%,g%,h%,%)" +# RUN: echo "%{f3}(f%,g%,h%,i%)" +# CHECK: %{f3}(%) +# CHECK: %{f3}(%,%) +# CHECK: %{f3}(f%,g%) +# CHECK: f3('', '', '') +# CHECK: f3('f', '', '') +# CHECK: f3('', 'g', '') +# CHECK: f3('', '', 'h') +# CHECK: f3('f', 'g', '') +# CHECK: f3('f', '', 'h') +# CHECK: f3('', 'g', 'h') +# CHECK: f3('f', 'g', 'h') +# CHECK: f3('fgh', 'ghi', 'hij') +# CHECK: %{f3}(%,%,%,%) +# CHECK: %{f3}(f%,%,%,%) +# CHECK: %{f3}(f%,g%,%,%) +# CHECK: %{f3}(f%,g%,h%,%) +# CHECK: %{f3}(f%,g%,h%,i%) + +# CHECK: Passed: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/actual-arg-special-chars.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/actual-arg-special-chars.txt @@ -0,0 +1,107 @@ +# Check that various sequences that are or look relevant to function +# substitutions behave correctly within actual arguments: +# +# - {name}( +# - ( +# - , +# - ) +# - %{name}( +# - %( +# - %, +# - %) +# - %%{name}( +# - %%( +# - %%, +# - %%) + +# %{fn}, %{call-a-b}, and substitutions defined before and after them. +# +# DEFINE: %{expand-last-fn}(p0 %, p1%) = expand-last-fn(%{p0},%{p1}) +# DEFINE: %{expand-last-str} = Goodbye world +# DEFINE: %{fn}(p0 %, p1 %, p2%)=fn('%{p0}', '%{p1}', '%{p2}') +# DEFINE: %{call-a-b}( FUNC %) = %{FUNC}( a %, b %) +# DEFINE: %{expand-first-fn}(p0 %, p1%) = expand-first-fn(%{p0},%{p1}) +# DEFINE: %{expand-first-str} = Hello world + +# Try each of these sequences in args: {name}( ( , ) +# +# RUN: echo "%{fn}( {expand-first-fn}(foo, bar)%, (foo,%, ,bar)%)" +# CHECK: fn('{expand-first-fn}(foo, bar)', '(foo,', ',bar)') + +# Make sure non-function substitutions are always fine in an arg. However, +# sorry, before they expand, they prevent expansion of the actual function use +# if they lexically look like function uses too: %{name}( +# +# RUN: echo "%{fn}( %{expand-first-str}() %, %{expand-first-str}( %, %) %, %)" +# RUN: echo "%{fn}( %{expand-last-str}() %, %{expand-last-str}( %, %) %, %)" +# CHECK: fn('Hello world()', 'Hello world(', '') %, %) +# CHECK-NON-RECUR: %{fn}( Goodbye world() %, Goodbye world( %, %) %, %) +# CHECK-RECUR: fn('Goodbye world()', 'Goodbye world(', '') %, %) + +# '%(' is not special. '%{name}%(' does not look like a function use. +# +# RUN: echo "%{fn}( %{expand-first-str}%() %, %{expand-first-str}%( %, %) %, %)" +# RUN: echo "%{fn}( %{expand-last-str}%() %, %{expand-last-str}%( %, %) %, %)" +# CHECK: fn('Hello world%()', 'Hello world%(', '') %, %) +# CHECK: fn('Goodbye world%()', 'Goodbye world%(', '') %, %) + +# Try each of these sequences in args: %%{name}( %%( %%, %%) +# Can we use those to fully escape a function substitution use within an arg? +# +# RUN: echo "%{fn}( %%{expand-first-fn}(a%%,b%%) %, %%{expand-first-fn}%%(a%%,b%%) %, %)" +# RUN: echo "%{fn}( %%{expand-last-fn}(a%%,b%%) %, %%{expand-last-fn}%%(a%%,b%%) %, %)" +# CHECK: fn('%{expand-first-fn}(a%,b%)', '%{expand-first-fn}%(a%,b%)', '') +# CHECK: fn('%{expand-last-fn}(a%,b%)', '%{expand-last-fn}%(a%,b%)', '') + +# In an arg of %{fn}, try to use %{expand-first-fn}. Both expand. +# +# RUN: echo "%{fn}( %, %{expand-first-fn}(a%,b%) %, %)" +# CHECK: fn('', 'expand-first-fn(a,b)', '') + +# In an arg of %{fn}, try to use %{expand-last-fn}. First, the use of %{fn} +# fails to expand because of the appearance of '%{expand-last-fn}(' in its arg. +# That's good because python's re package cannot balance parentheses, and we +# don't want to match the wrong '%)' after '%{fn}(' (without the restriction +# against a function use in the arg, that match would have been possible at the +# first '%)' because the correct number of remaining '%,' for %{fn} appear +# before it). Next, the use of %{expand-last-fn} expands. If +# recursiveExpansionLimit were >=2, the use of %{fn} would then expand. +# +# RUN: echo "%{fn}( %, %{expand-last-fn}(a%,b%) %, %)" +# CHECK-NON-RECUR: %{fn}( %, expand-last-fn(a,b) %, %) +# CHECK-RECUR: fn('', 'expand-last-fn(a,b)', '') + +# What happens when a function substitution is used in its own arg? Again, we +# must make sure the inner use expands first. Otherwise, the outer use would +# close at the inner uses's '%)'. We need recursiveExpansionLimit>=2 to expand +# the outer use. +# +# RUN: echo "%{fn}( %{fn}(a %, b %, c %) %, %, %)" +# CHECK-NON-RECUR: %{fn}( fn('a', 'b', 'c') %, %, %) +# CHECK-RECUR: fn('fn('a', 'b', 'c')', '', '') + +# Make sure we always match the first '%)'. In this case, the second arg in the +# use of %{expand-first-fn} would extend to the '%)' that pairs with '%{fn}(', +# but it doesn't because we don't permit '%)' in an argument. +# +# RUN: echo "%{fn}( %, %, %{expand-first-fn}(a%,b%) %)" +# RUN: echo "%{fn}( %, %, %{expand-last-fn}(a%,b%) %)" +# CHECK: fn('', '', 'expand-first-fn(a,b)') +# CHECK-NON-RECUR: %{fn}( %, %, expand-last-fn(a,b) %) +# CHECK-RECUR: fn('', '', 'expand-last-fn(a,b)') + +# In an arg, can we use a function substitution's name without arguments? The +# latter shouldn't expand. +# +# RUN: echo "%{fn}(%{expand-first-fn} %, %{expand-last-fn} %, %{fn} %)" +# CHECK: fn('%{expand-first-fn}', '%{expand-last-fn}', '%{fn}') + +# That means we can effectively pass around function pointers. +# +# RUN: echo "%{call-a-b}( %{expand-last-fn} %)" +# RUN: echo "%{call-a-b}( %{expand-first-fn} %)" +# CHECK: expand-last-fn(a,b) +# CHECK-NON-RECUR: %{expand-first-fn}( a %, b %) +# CHECK-RECUR: expand-first-fn(a,b) + +# CHECK: Passed: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/bare-comma.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/bare-comma.txt @@ -0,0 +1,9 @@ +# DEFINE: %{name}( PARAM1%, PARAM2, PARAM3%, PARAM4 %) = value +# RUN: echo %{name} + +# CHECK: Parameter 2 of substitution '%{name}' is malformed as {{.*}} +# CHECK-NEXT: Parameter 2 is: PARAM2, PARAM3 +# CHECK-NEXT: Parameter names must be separated by '%,' +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-6]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/bare-rparen.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/bare-rparen.txt @@ -0,0 +1,7 @@ +# DEFINE: %{name}(PARAM1) = value +# RUN: echo %{name} + +# CHECK: Parameter list of substitution '%{name}' must end with '%)' +# CHECK-NEXT: in {{DEFINE}}: directive on test line 1 + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/between-name-equals.txt =================================================================== --- llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/between-name-equals.txt +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/between-name-equals.txt @@ -1,9 +1,7 @@ -# ':' is treated like part of the name, so the name is bad. - # DEFINE: %{name}:=value # RUN: echo %{name} -# CHECK: Substitution name '%{name}:' is malformed {{.*}} +# CHECK: Substitution name '%{name}' must be followed by '=' (possibly with intervening whitespace) or by '(' (without intervening whitespace) # CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-4]] # CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/between-name-lparen.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/between-name-lparen.txt @@ -0,0 +1,7 @@ +# DEFINE: %{name} ( PARAM %) = value +# RUN: echo %{name} + +# CHECK: Substitution name '%{name}' must be followed by '=' (possibly with intervening whitespace) or by '(' (without intervening whitespace) +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-4]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/no-comma.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/no-comma.txt @@ -0,0 +1,9 @@ +# DEFINE: %{name}( PARAM1 PARAM2 %) = value +# RUN: echo %{name} + +# CHECK: Parameter 1 of substitution '%{name}' is malformed as {{.*}} +# CHECK-NEXT: Parameter 1 is: PARAM1 PARAM2 +# CHECK-NEXT: Parameter names must be separated by '%,' +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-6]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/no-rparen.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/no-rparen.txt @@ -0,0 +1,7 @@ +# DEFINE: %{name}( PARAM1 = value +# RUN: echo %{name} + +# CHECK: Parameter list of substitution '%{name}' must end with '%)' +# CHECK-NEXT: in {{DEFINE}}: directive on test line 1 + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-list-is-empty-string.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-list-is-empty-string.txt @@ -0,0 +1,7 @@ +# DEFINE: %{name}(%) = value +# RUN: echo %{name} + +# CHECK: Substitution '%{name}' must be defined with no parameter list or at least one parameter +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-4]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-list-is-ws.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-list-is-ws.txt @@ -0,0 +1,7 @@ +# DEFINE: %{name}( %) = value +# RUN: echo %{name} + +# CHECK: Substitution '%{name}' must be defined with no parameter list or at least one parameter +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-4]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-name-leading-digit.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-name-leading-digit.txt @@ -0,0 +1,11 @@ +# A parameter name must be a valid python identifier for the function +# substitution's pattern to work, and leading digits are not permitted. + +# DEFINE: %{foo}( 0PARAM %) = %{0PARAM} +# RUN: echo %{foo} + +# CHECK: Parameter 1 of substitution '%{foo}' is malformed as {{.*}} +# CHECK-NEXT: Parameter 1 is: 0PARAM +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-5]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-name-with-braces.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-name-with-braces.txt @@ -0,0 +1,10 @@ +# For conciseness, parameter names are unbraced in the formal parameter list. + +# DEFINE: %{foo}( %{PARAM} %) = %{PARAM} +# RUN: echo %{foo} + +# CHECK: Parameter 1 of substitution '%{foo}' is malformed as {{.*}} +# CHECK-NEXT: Parameter 1 is: %{PARAM} +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-5]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-name-with-dash.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/assignment/param-name-with-dash.txt @@ -0,0 +1,11 @@ +# A parameter name must be a valid python identifier for the function +# substitution's pattern to work, and dashes are not permitted. + +# DEFINE: %{foo}( MY-PARAM %) = %{MY-PARAM} +# RUN: echo %{foo} + +# CHECK: Parameter 1 of substitution '%{foo}' is malformed as {{.*}} +# CHECK-NEXT: Parameter 1 is: MY-PARAM +# CHECK-NEXT: in {{DEFINE}}: directive on test line [[#@LINE-5]] + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already-diff-param-count.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already-diff-param-count.txt @@ -0,0 +1,9 @@ +# DEFINE: %{foo}( PARAM0 %) = %{PARAM0} +# DEFINE: %{foo}( PARAM0 %, PARAM1 %) = %{PARAM0}, %{PARAM1} +# RUN: echo %{foo} + +# CHECK: ValueError: Substitution whose pattern contains '%{foo}' is already defined before '{{DEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Existing pattern: %{foo}\({{.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already-diff-param-name.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already-diff-param-name.txt @@ -0,0 +1,9 @@ +# DEFINE: %{foo}( PARAM0 %) = %{PARAM0} +# DEFINE: %{foo}( PARAM1 %) = %{PARAM1} +# RUN: echo %{foo} + +# CHECK: ValueError: Substitution whose pattern contains '%{foo}' is already defined before '{{DEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Existing pattern: %{foo}\({{.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already-non-func.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already-non-func.txt @@ -0,0 +1,9 @@ +# DEFINE: %{foo} = bar +# DEFINE: %{foo}( PARAM %) = %{PARAM} +# RUN: echo %{foo}(bar) + +# CHECK: ValueError: Substitution whose pattern contains '%{foo}' is already defined before '{{DEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Existing pattern: %{foo} +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-func-already.txt @@ -0,0 +1,9 @@ +# DEFINE: %{foo}( PARAM %) = %{PARAM} +# DEFINE: %{foo}( PARAM %) = %{PARAM} +# RUN: echo %{foo} + +# CHECK: ValueError: Substitution whose pattern contains '%{foo}' is already defined before '{{DEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Existing pattern: %{foo}\({{.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-non-func-already-func.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/define-non-func-already-func.txt @@ -0,0 +1,9 @@ +# DEFINE: %{foo}( PARAM %) = %{PARAM} +# DEFINE: %{foo} = bar +# RUN: echo %{foo} + +# CHECK: ValueError: Substitution whose pattern contains '%{foo}' is already defined before '{{DEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Existing pattern: %{foo}\({{.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-func-already-diff-param-count.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-func-already-diff-param-count.txt @@ -0,0 +1,10 @@ +# DEFINE: %{foo}( PARAM0 %) = %{PARAM0} +# REDEFINE: %{foo}( PARAM0 %, PARAM1 %) = %{PARAM0}, %{PARAM1} +# RUN: echo %{foo} + +# CHECK: ValueError: Existing substitution whose pattern contains '%{foo}' does not have the pattern specified by '{{REDEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Expected pattern: %{foo}\({{.*PARAM0.*PARAM1.*}}\) +# CHECK-NEXT: Existing pattern: %{foo}\({{.*PARAM0.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-func-already-diff-param-name.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-func-already-diff-param-name.txt @@ -0,0 +1,10 @@ +# DEFINE: %{foo}( PARAM0 %) = %{PARAM0} +# REDEFINE: %{foo}( PARAM1 %) = %{PARAM1} +# RUN: echo %{foo} + +# CHECK: ValueError: Existing substitution whose pattern contains '%{foo}' does not have the pattern specified by '{{REDEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Expected pattern: %{foo}\({{.*PARAM1.*}}\) +# CHECK-NEXT: Existing pattern: %{foo}\({{.*PARAM0.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-func-already-non-func.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-func-already-non-func.txt @@ -0,0 +1,10 @@ +# DEFINE: %{foo} = bar +# REDEFINE: %{foo}( PARAM %) = %{PARAM} +# RUN: echo %{foo} + +# CHECK: ValueError: Existing substitution whose pattern contains '%{foo}' does not have the pattern specified by '{{REDEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Expected pattern: %{foo}\({{.*}}\) +# CHECK-NEXT: Existing pattern: %{foo} +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-non-func-already-func.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/errors/defined-check/redefine-non-func-already-func.txt @@ -0,0 +1,10 @@ +# DEFINE: %{foo}( PARAM %) = %{PARAM} +# REDEFINE: %{foo} = bar +# RUN: echo %{foo} + +# CHECK: ValueError: Existing substitution whose pattern contains '%{foo}' does not have the pattern specified by '{{REDEFINE}}:' directive at line [[#@LINE-3]] +# CHECK-NEXT: Expected pattern: %{foo} +# CHECK-NEXT: Existing pattern: %{foo}\({{.*}}\) +# CHECK-NOT: Existing pattern: + +# CHECK: Unresolved: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/examples/function-subst-with-locs.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/examples/function-subst-with-locs.txt @@ -0,0 +1,30 @@ +; This example originally appeared in TestingGuide.rst except here we've added +; echo to the clang/FileCheck command line to be executed. + +; DEFINE: %{check}( LOC %, TRIPLE %, CFLAGS %, FCFLAGS %) = \ +; DEFINE: echo 'At test lines %{LOC}, %(line)' && \ +; DEFINE: echo ' \ +; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{CFLAGS} \ +; DEFINE: -triple %{TRIPLE} -emit-llvm -o - %s | \ +; DEFINE: FileCheck %{FCFLAGS} %s \ +; DEFINE: ' + +; DEFINE: %{check-triples}( LOC %, CFLAGS %, FCFLAGS %) = \ +; DEFINE: %{check}( %{LOC}, %(line) %, x86_64-apple-darwin10.6.0 %, \ +; DEFINE: %{CFLAGS} %, %{FCFLAGS} %) && \ +; DEFINE: %{check}( %{LOC}, %(line) %, x86_64-unknown-linux-gnu %, \ +; DEFINE: %{CFLAGS} %, %{FCFLAGS} %) + +; RUN: %{check-triples}( %(line) %, -fopenmp-simd %, -check-prefix=SIMD %) +; CHECK: At test lines [[#@LINE-1]], [[#@LINE-6]], [[#@LINE-14]] +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - {{.*}} | FileCheck -check-prefix=SIMD {{.*}} +; CHECK: At test lines [[#@LINE-3]], [[#@LINE-6]], [[#@LINE-16]] +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -fopenmp-simd -triple x86_64-unknown-linux-gnu -emit-llvm -o - {{.*}} | FileCheck -check-prefix=SIMD {{.*}} + +; RUN: %{check-triples}( %(line) %, %, -check-prefix=NO-SIMD %) +; CHECK: At test lines [[#@LINE-1]], [[#@LINE-12]], [[#@LINE-20]] +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - {{.*}} | FileCheck -check-prefix=NO-SIMD {{.*}} +; CHECK: At test lines [[#@LINE-3]], [[#@LINE-12]], [[#@LINE-22]] +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -triple x86_64-unknown-linux-gnu -emit-llvm -o - {{.*}} | FileCheck -check-prefix=NO-SIMD {{.*}} + +; CHECK: Passed: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/examples/function-subst.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/examples/function-subst.txt @@ -0,0 +1,25 @@ +; This example originally appeared in TestingGuide.rst except here we've added +; echo to the clang/FileCheck command line to be executed. + +; DEFINE: %{check}( TRIPLE %, CFLAGS %, FCFLAGS %) = \ +; DEFINE: echo ' \ +; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{CFLAGS} \ +; DEFINE: -triple %{TRIPLE} -emit-llvm -o - %s | \ +; DEFINE: FileCheck %{FCFLAGS} %s \ +; DEFINE: ' + +; DEFINE: %{check-triples}( CFLAGS %, FCFLAGS %) = \ +; DEFINE: %{check}( x86_64-apple-darwin10.6.0 %, %{CFLAGS} %, \ +; DEFINE: %{FCFLAGS} %) && \ +; DEFINE: %{check}( x86_64-unknown-linux-gnu %, %{CFLAGS} %, \ +; DEFINE: %{FCFLAGS} %) + +; RUN: %{check-triples}( -fopenmp-simd %, -check-prefix=SIMD %) +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - {{.*}} | FileCheck -check-prefix=SIMD {{.*}} +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -fopenmp-simd -triple x86_64-unknown-linux-gnu -emit-llvm -o - {{.*}} | FileCheck -check-prefix=SIMD {{.*}} + +; RUN: %{check-triples}( %, -check-prefix=NO-SIMD %) +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - {{.*}} | FileCheck -check-prefix=NO-SIMD {{.*}} +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -triple x86_64-unknown-linux-gnu -emit-llvm -o - {{.*}} | FileCheck -check-prefix=NO-SIMD {{.*}} + +; CHECK: Passed: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/examples/param-and-function-subst.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-define/examples/param-and-function-subst.txt @@ -0,0 +1,30 @@ +; This example originally appeared in TestingGuide.rst except here we've added +; echo to the clang/FileCheck command line to be executed. + +; DEFINE: %{cflags} = +; DEFINE: %{fcflags} = + +; DEFINE: %{check}( TRIPLE %) = \ +; DEFINE: echo ' \ +; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{cflags} \ +; DEFINE: -triple %{TRIPLE} -emit-llvm -o - %s | \ +; DEFINE: FileCheck %{fcflags} %s \ +; DEFINE: ' + +; DEFINE: %{check-triples} = \ +; DEFINE: %{check}( x86_64-apple-darwin10.6.0 %) && \ +; DEFINE: %{check}( x86_64-unknown-linux-gnu %) + +; REDEFINE: %{cflags} = -fopenmp-simd +; REDEFINE: %{fcflags} = -check-prefix=SIMD +; RUN: %{check-triples} +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - {{.*}} | FileCheck -check-prefix=SIMD {{.*}} +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -fopenmp-simd -triple x86_64-unknown-linux-gnu -emit-llvm -o - {{.*}} | FileCheck -check-prefix=SIMD {{.*}} + +; REDEFINE: %{cflags} = +; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD +; RUN: %{check-triples} +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - {{.*}} | FileCheck -check-prefix=NO-SIMD {{.*}} +; CHECK: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -triple x86_64-unknown-linux-gnu -emit-llvm -o - {{.*}} | FileCheck -check-prefix=NO-SIMD {{.*}} + +; CHECK: Passed: 1 Index: llvm/utils/lit/tests/Inputs/shtest-define/ws-and-continuations.txt =================================================================== --- llvm/utils/lit/tests/Inputs/shtest-define/ws-and-continuations.txt +++ llvm/utils/lit/tests/Inputs/shtest-define/ws-and-continuations.txt @@ -4,47 +4,100 @@ # DEFINE: %{empty}= # RUN: echo "'%{empty}'" # CHECK:'' +# +# REDEFINE: %{empty}= +# RUN: echo "'%{empty}'" +# CHECK:'' + +# A value consisting only of whitespace is trimmed to the empty string. +# +# v~~ intentional whitespace +# DEFINE: %{ws}= +# RUN: echo "'%{ws}'" +# CHECK:'' +# +# v intentional whitespace +# REDEFINE: %{ws}= +# RUN: echo "'%{ws}'" +# CHECK:'' # White space is not required around the name or value. # -# DEFINE:%{no-whitespace}=abc -# RUN: echo "'%{no-whitespace}'" +# DEFINE:%{non-ws}=abc +# RUN: echo "'%{non-ws}'" # CHECK:'abc' # -# REDEFINE:%{no-whitespace}=HelloWorld -# RUN: echo "'%{no-whitespace}'" +# REDEFINE:%{non-ws}=HelloWorld +# RUN: echo "'%{non-ws}'" # CHECK:'HelloWorld' -# Exact white space is preserved within the value, but whitespace enclosing the -# name or value is discarded. ('%{' and '}' are part of the name, and -# whitespace in between isn't permitted.) +# White space is not required around formal parameters or arguments. +# +# DEFINE:%{non-ws-fn}(P0%,P1%,P2%)=non-ws-fn(%{P0},%{P1},%{P2}) +# RUN: echo "'%{non-ws-fn}(a%,b%,c%)'" +# CHECK:'non-ws-fn(a,b,c)' +# +# REDEFINE:%{non-ws-fn}(P0%,P1%,P2%)=non-ws-fn(%{P2},%{P1},%{P0}) +# RUN: echo "'%{non-ws-fn}(a%,b%,c%)'" +# CHECK:'non-ws-fn(c,b,a)' + +# Exact white space is preserved within the value or an actual arg, but +# whitespace enclosing the name, the value, a formal parameter, or an actual arg +# is discarded. ('%{' and '}' are part of the name, and whitespace in between +# isn't permitted.) # -# v~~ intentional whitespace -# DEFINE: %{whitespace} = abc def -# RUN: echo "'%{whitespace}'" +# v~~ intentional whitespace +# DEFINE: %{ws-non-ws} = abc def +# v~ intentional whitespace +# DEFINE: %{ws-non-ws-fn}( P0 %, P1 %) = <%{P0}> <%{P1}> +# RUN: echo "'%{ws-non-ws}'" +# RUN: echo "'%{ws-non-ws-fn}( abc def %, ghi jkl %)'" # CHECK:'abc def' -# v intentional whitespace -# REDEFINE: %{whitespace} = Hello World -# RUN: echo "'%{whitespace}'" +# CHECK:' ' +# v intentional whitespace +# REDEFINE: %{ws-non-ws} = Hello World +# v intentional whitespace +# REDEFINE: %{ws-non-ws-fn}( P0 %, P1 %) = <%{P0}> <%{P1}> +# RUN: echo "'%{ws-non-ws}'" +# RUN: echo "'%{ws-non-ws-fn}( a b c %, d e %)'" # CHECK:'Hello World' +# CHECK:' ' # Line continuations in the value are permitted and collapse whitespace. # -# DEFINE: %{continue} = abc\ +# DEFINE: %{value-continue} = abc\ # DEFINE:def \ # DEFINE:ghi\ # DEFINE: jkl \ # DEFINE: mno \ # DEFINE: pqr # ^ intentional whitespace -# RUN: echo "'%{continue}'" +# RUN: echo "'%{value-continue}'" # CHECK:'abc def ghi jkl mno pqr' # -# REDEFINE: %{continue} = abc \ +# REDEFINE: %{value-continue} = abc \ # REDEFINE: def -# RUN: echo "'%{continue}'" +# RUN: echo "'%{value-continue}'" # CHECK:'abc def' +# Line continuations in formal parameters and actual arguments are permitted. +# +# DEFINE: %{params-continue}( \ +# DEFINE: PARAM0 %, PARAM1 %, PARAM2 %, PARAM3 %, \ +# DEFINE: PARAM4 %, PARAM5 %, PARAM6 %, PARAM7 %, \ +# DEFINE: PARAM8 %, PARAM9 %, PARAM10 %, PARAM11 %) = \ +# DEFINE: %{PARAM0} %{PARAM1} %{PARAM2} %{PARAM3} \ +# DEFINE: %{PARAM4} %{PARAM5} %{PARAM6} %{PARAM7} \ +# DEFINE: %{PARAM8} %{PARAM9} %{PARAM10} %{PARAM11} +# RUN: echo "'%{params-continue}( \ +# RUN: a %, b %, \ +# RUN: c %, d %, \ +# RUN: e %, f %, \ +# RUN: g %, h %, \ +# RUN: i %, j %, \ +# RUN: k %, l %)'" +# CHECK:'a b c d e f g h i j k l' + # Whitespace at the end of the line after a '\' is ignored, and it's treated as # a line continuation. Otherwise, the behavior would be hard to understand # because it looks like a line continuation. Index: llvm/utils/lit/tests/shtest-define.py =================================================================== --- llvm/utils/lit/tests/shtest-define.py +++ llvm/utils/lit/tests/shtest-define.py @@ -15,12 +15,36 @@ # DEFINE: FileCheck -match-full-lines %{fc-args} %{my-inputs}/%{test} # DEFINE: %{run-and-record-test} = %{run-test} && %{record-test} +# REDEFINE: %{test} = actual-arg-catastrophic-backtracking.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = actual-arg-count.txt +# RUN: %{run-and-record-test} + +# REDEFINE: %{test} = actual-arg-special-chars.txt +# +# REDEFINE: %{fc-args} = -check-prefixes=CHECK,CHECK-NON-RECUR +# RUN: %{run-test} +# +# REDEFINE: %{lit-args} = -Drecur=2 +# REDEFINE: %{fc-args} = -check-prefixes=CHECK,CHECK-RECUR +# RUN: %{run-test} +# +# RUN: %{record-test} +# REDEFINE: %{lit-args} = +# REDEFINE: %{fc-args} = + # REDEFINE: %{lit-pre} = not # +# REDEFINE: %{test} = errors/assignment/bare-comma.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/bare-rparen.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/before-name.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/between-name-equals.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/between-name-lparen.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/braces-empty.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/braces-with-dot.txt @@ -35,10 +59,24 @@ # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/empty.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/no-comma.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/no-equals.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/no-name.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/no-rparen.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/param-list-is-empty-string.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/param-list-is-ws.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/param-name-leading-digit.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/param-name-with-braces.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/assignment/param-name-with-dash.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/assignment/ws-only.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/continuation/empty.txt @@ -71,22 +109,40 @@ # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/define-already-by-test.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/define-func-already-diff-param-count.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/define-func-already-diff-param-name.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/define-func-already-non-func.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/define-func-already.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/define-inside-pattern.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/define-multiple-exact.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/define-multiple-once-exact.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/define-non-func-already-func.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/define-prefixes-pattern.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/define-suffixes-pattern.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/redefine-func-already-diff-param-count.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/redefine-func-already-diff-param-name.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/redefine-func-already-non-func.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/redefine-inside-pattern.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/redefine-multiple-exact.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/redefine-multiple-once-exact.txt # RUN: %{run-and-record-test} +# REDEFINE: %{test} = errors/defined-check/redefine-non-func-already-func.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/redefine-none.txt # RUN: %{run-and-record-test} # REDEFINE: %{test} = errors/defined-check/redefine-prefixes-pattern.txt @@ -100,6 +156,12 @@ # # REDEFINE: %{lit-pre} = +# REDEFINE: %{test} = examples/function-subst-with-locs.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = examples/function-subst.txt +# RUN: %{run-and-record-test} +# REDEFINE: %{test} = examples/param-and-function-subst.txt +# RUN: %{run-and-record-test} # REDEFINE: %{test} = examples/param-subst.txt # RUN: %{run-and-record-test}