<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/tests/preprocessor/macros, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2021-06-16T21:35:25+00:00</updated>
<entry>
<title>Initial support for variadic macros (#1887)</title>
<updated>2021-06-16T21:35:25+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2021-06-16T21:35:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=89051251016be7d3798c0b9586c6db7b4ed5f21d'/>
<id>urn:sha1:89051251016be7d3798c0b9586c6db7b4ed5f21d</id>
<content type='text'>
This change adds support for variadic macros in the C-style
preprocessor, e.g.:

    #define DEBUG(MSG, ...) print(__FILE__, __LINE__, MSG, __VA_ARGS__)

Similar to the gcc preprocessor, this feature supports both named
variadic macro parameters and unnamed ones (which then default to
`__VA_ARGS__`.

The implementation work is mostly straightforward, although there are a
few subtle design choices worth mentioning:

* A variadic macro is represented by it having a variadic *parameter*
  that is part of the ordinary parameter list.

* Argument parsing does *not* detect whether the macro being invoked is
  variadic and collect/combine arguments to form a single argument value
  for the variadic parameter. This is motivated by the need for some
  extensions to differentiate a variadic parameter receiving a single
  empty argument vs. zero arguments.

* Because any reference to the variadic parameter needs to expand to the
  comma-separated arguments that match it, the logic for turning a macro
  parameter reference into a list of tokens has been factored out into a
  subroutine that handles the details.

* The choice in the earlier refactor to have a macro invocation collect
  all the argument tokens (including the intervening commas) into a
  single token list seems to pay off here, because it means that the
  tokens in the expansion of a variadic parameter reference were already
  stored contiguously.

* The special-case logic for handling an empty argument list had to be
  tweaked again to ensure that an empty argument list is treated as
  having zero arguments for the variadic parameter. Note that
  historically C did not define the behavior of this case, and always
  required at least one argument for any variadic macro parameter.

* The logic for checking whether the number of arguments to a macro
  invocation is valid needed to handle variadic and non-variadic macros
  as distinct cases. There really isn't much overlap in how the checks
  need to work, even if we tried to change the underling representation.

The main missing feature here is any way to discard a comma in a macro
body that appears before a variadic parameter reference, e.g.:

    #define DEBUG(...) print("debug:", __VA_ARGS__)

In this case, an empty invocation list `DEBUG()` will expand to
`print("debug:",)` - a call with a trailing comma in the argument list.

If users end up needing a way to discard commas in cases like this, we
have many options we can consider. This change does not implement any of
them to keep the initial work as minimal as possible.</content>
</entry>
<entry>
<title>Fix a bug in preprocessor "busy" logic (#1875)</title>
<updated>2021-06-06T15:59:28+00:00</updated>
<author>
<name>T. Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2021-06-06T15:59:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=58d7af37f45f88130641188b1e39b00569acd575'/>
<id>urn:sha1:58d7af37f45f88130641188b1e39b00569acd575</id>
<content type='text'>
* Fix a bug in preprocessor "busy" logic

This bug manifested in both incorrect preprocessor output for certain complicated cases, and also (more importantly) a use-after-free issue.

One of the "clever" design choices in the Slang preprocessor implementation is that the set of "busy" macros during expansion is implicitly defined by a linked list of those invocations that are actively being read from as part of the input stack. This logic works very well for checking whether a macro name is busy before triggering expansion, and for computing what macros should be considered busy during expansion of an object-like macro.

The problem case here was with function-like macros where the preprocessor was re-using the same list of busy macros that had been fetched when reading the macro name, but doing so *after* all the macro argument tokens had been read. Because additional tokens had been read from the input stream stack, there was no guarantee that the invocations that had been active before were still live.

The new logic computes the set of busy macros fresh before starting expansion of a function-like macro invocation. A test is included to ensure that the case that showed the use-after-free bug has been fixed.

In addition, the new logic is careful to compute the busy macros only based on where subsequent tokens will come from and not based on any macros that might have contributed to the argument tokens themselves. A test case has been added that relies on getting this detail correct.

* Update slang-preprocessor.cpp

Remove a test typo.

Co-authored-by: jsmall-nvidia &lt;jsmall@nvidia.com&gt;</content>
</entry>
</feed>
