| Commit message (Collapse) | Author | Age |
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Implemented #pragma warning
Based on https://learn.microsoft.com/en-us/cpp/preprocessor/warning?view=msvc-170
* Make #pragma warning work with #includes.
- SourceLoc are not sorted by inclusion order.
- Construct a mapping from SourceLoc to "absolute locations" that are sorted by inclusion order (roughly represents a location in a raw file with all #include resolved).
- The absolute location can be used in the pragma warning timeline
* Added preprocessor #pragma warning tests.
- Fixed #pragma warning (push / pop) SourceLoc
- Fixed unused directiveLoc in #pragma warning parsing
* #pragma warning: Added some comments and fixed some typos
* Cleaned #pragma warning preprocessor implementation.
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
| |
Co-authored-by: Jay Kwak <82421531+jkwak-work@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Respect explicit bindings in wgsl emit.
* Implement explciit binding generation for metal and wgsl.
* Update toc.
* Fix warnings in tests.
* Fix tests.
---------
Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
|
| |
|
|
|
|
|
| |
* format
* Minor test fixes
* enable checking cpp format in ci
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Slang APIs are documented as taking UTF-8 encoded shader source,
though it's not explicitly documented whether it is allowed to
include a BOM (Byte Order Marker). This change adds support for
UTF-8 BOM markers by virtue of disposing of BOM data. As a bonus,
UTF-16 input which can cleanly decode to UTF-8 is now also
accepted.
Throwing out the BOM on input is done by leveraging existing
functionality in "determineEncoding()", however a bug exists there
for null-terminated single character input, where the null byte
caused a heuristic to guess UTF-16, even though the null byte
isn't part of the string. The bug in "determineEncoding" is fixed
by only guessing when bytes >= 2 and not looking past the end
of the buffer. The 'implicit-cast' test was mistakenly relying
on the bug to pass, as its expected file was being read as UTF16
and cropped to zero length due to the bug. The expected output
of implicit-cast is updated to pass with the bug fix in place.
The decoding of UTF-16 to UTF-8 is done through an existing
'decode' method. This change fixes a bug in UTF16-LE 'decode'
where it was decoded as if it were Big-Endian.
Adds 3 small tests to ensure the compiler doesn't choke on source
files in UTF-8 (with BOM), UTF16-LE, or UTF16-BE.
Bonus: Fixes a bug in diagnostic reporting where hex values were
incorrectly translated to text, leading to incorrect, possibly
truncated strings.
Fixes #4046
Co-authored-by: Yong He <yonghe@outlook.com>
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
* A more way robust way to handle resource consumption might use multiple `kind`s on GLSL emit.
* Improve method naming and some comments.
* Small consistency fix.
* Fix issue with #elif evaluation.
* Add a test.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#2958)
* Simplify type of diagnoseImpl
* Show source line for Note diagnostics, opting out of this where appropriate
* Make declared after use diagnostic clearer
* Fix erroneous error claiming variable is being used before its declaration
Closes https://github.com/shader-slang/slang/issues/2936
* Fix build on msvc
---------
Co-authored-by: jsmall-nvidia <jsmall@nvidia.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
* #include an absolute path didn't work - because paths were taken to always be relative.
* Add standard macros including __HLSL_VERSION
* Added hlsl test.
* Defined standard macro names to values, so not undefined. Allows more convenient #if style.
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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 <jsmall@nvidia.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Overhaul the preprocessor
The old Slang preprocessor was based on a simple mental model that tried to unify two parts of macro expansion:
* Scanning for macro invocations in a sequence of tokens
* Producing the expanded tokens for a macro expansion by substituting arguments into its body
The basic was that substitution of macro arguments into a macro definition is superficially similar to top-level macro expansion, just with an environment where the macro arguments act like `#define`s for the corresponding parameter names. That approach was "clever" and could conceivably have been extended to include a lot of advanced preprocessor features (e.g., a preprocessor-level `lambda` would be easy to support!), but it was basically impossible to make it correctly handle all the corner cases of the full C/C++ preprocessor.
The fundamental problem with the old approach was that it conflated the two parts of expansion listed above into one implementation, while the various special cases of the C/C++ preprocessor rely on treating the two cases very differently. The new approach here (which is somewhere between a refactor and a full rewrite of the preprocessor) changes things up in a few key ways:
* The abstraction still cares a lot about streams of tokens, but it now treats the top level streams (`InputFile`s) as fairly different from the lower-level streams (`InputStream`s)
* Macro expansion is handled as a dedicated type of stream that wraps another stream. This allows macro expansion to be applied to anything, and supports cases where multiple rounds of macro expansion are required by the spec.
* Macro *invocations* and the substitution of their arguments are now handled by a completely new system.
* Macro arguments are no longer treated as if they were `#define`s
* The macro body/definition is analyzed at definition time to detect various kinds of issues, and to derive a list of "ops" that make it easier to "play back" the definition at substitution time
* Token pasting and stringizing are now only handled in macro definitions (rather than being allowed anywhere), and their use cases are restricted to only those that make sense (e.g., you can't stringize anythign except a macro parameter, because anything else wouldn't make sense)
The key new types here are the `ExpansionInputStream` which handles scanning for macro invocations, and the `MacroInvocation` type, which handles playing back the macro body with substitutions.
The `ExpansionInputStream` is the easier of the two to understand. By refactoring it to use a single token of lookahead, the one major detail it had to deal with before (abandoning expansion of a function-like macro if the macro name was not followed by `(`) is significantly easier to manage.
The more subtle part is the `MacroInvocation` type, and most of the complexity there is around handling of token pasting, and the fact that either or both of the operands to a token paste might be empty.
Many of the test cases that exposed the problems in the preprocessor have been moved from `current-bugs` to `preprocessor` since they now work correctly.
* debugging: enable extractor command line dump
* fixup
* fixup
|
| |
|
|
|
|
|
| |
* #include an absolute path didn't work - because paths were taken to always be relative.
* Added a current-bugs folder in tests for active (ie with issue) bug tests demonstrating the problem.
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* #include an absolute path didn't work - because paths were taken to always be relative.
* First pass support for __LINE__ and __FILE__.
* Test include handling with __FILE__
Fix diagnostic compare when input is empty.
* Fix some issues in preprocessor handling of special macros like __LINE__
Add a more complex test.
* Use CONCAT2 in tests, because preprocessor doesn't quite get parameter expansion correct.
* Make __FILE__ and __LINE__ behave more like Clang/Gcc.
* A test for preprocessor bug.
* Fix __LINE__ and __FILE__ in macro expansion, should be initiating location.
* Fix some comments.
* Small tidy up around builtin macros.
* Small improvements for macro type names.
Escape found paths.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The underlying problem here requires that we have an object-like macro with an expansion that starts with a non-identifier token:
```
```
Then we need a function-like macro that uses a token paste in a way that can expand to that object-like macro:
```
```
Finally, for the specific case a user ran into, we need to invoke that function-like macro in the context of a preprocessor conditional expression:
```
// ...
#error "unimplemented"
```
The way a problem manifest is that the preprocessor logic that handles conditional expressions tries to "peek" one token ahead and see what is coming, and while the peeking logic handles macro expansion it does *not* handle token pasting right now. That means that the peek operation sees `MY_FEATURE` and assumes that it is seeing an identifier in a preprocessor conditional that doesn't have a macro expansion. The logic then goes on to read the token, but what it gets back is *not* an identifier, and is instead the numeric literal token `1`, because the reading logic handles token pasting.
The quick fix I applied here is to make the logic that deals with preprocessor conditionals go ahead and automatically consume a token from the input, and then decide what to do based on that token, so that it always makes use of the reading logic that handles token pasting.
The lingering problem is that we still have cases in the preprocessor that use the peeking logic which doesn't handle pasting, and we might find that those cases have reason to want the same kind of expansion behavior we needed here. A more systematic fix would be to have the peeking logic automatically handle token pasting as well as macro expansion, but doing so would be a more complicated change because detecting the `##` when peeking ahead requires two tokens of lookahead, and our current implementation only assumes we can support one.
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* #include an absolute path didn't work - because paths were taken to always be relative.
* WIP: First pass in supporting output of line error information.
* Add support for lexing to better be able to indicate SourceLocation information.
* Fix lexer usage in DiagnosticSink in C++ extractor.
* Update diagnostics tests to have line location info.
* Fixed test expected output that now have source location information in them.
* Better handling of tab.
* Fix test expected results for tabbing change.
* DiagnosticLexer -> DiagnosticSink::SourceLocationLexer
Added line continuation tests.
* Fix typo.
* Added String::appendRepeatedChar
* Change to rerun tests.
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* #include an absolute path didn't work - because paths were taken to always be relative.
* Improve diagnostic for token pasting.
* Token paste location test.
* Output include hierarchy.
* WIP on includes hierarchy.
* Improved include hierarchy output - to handle source files without tokens.
Improved test case.
* Small comment improvements.
Fixed a typo with not returning a reference.
* Slight simplification of the ViewInitiatingHierarchy, by adding GetOrAddValue to Dictionary.
* Remove the need for ViewInitiatingHierarchy type.
* Improve output of path in diagnostic for includes hierarchy.
* Remove comment in diagnostic for token-paste-location.slang
* Update command line docs to include `-output-includes`
Co-authored-by: Yong He <yonghe@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix premake5.lua so it uses the new path needed for OpenCLDebugInfo100.h
* Keep including the includes directory.
* Added the spirv-tools-generated files.
* We don't need to include the spirv/unified1 path because the files needed are actually in the spirv-tools-generated folder.
* Put the build_info.h glslang generated files in external/glslang-generated. Alter premake5.lua to pick up that header.
* First pass at documenting how to build glslang and spirv-tools.
* Improved glsl/spir-v tools README.md
* Added revision.h
* Change how gResources is calculated.
Update about revision.h
* Update docs a little.
* Split out spirv-tools into a separate project for building glslang. This was not necessary on linux, but *is* necessary on windows, because there is a file disassemble.cpp in spirv-tools and in glslang, and this leads to VS choosing only one. With the separate library, the problem is resolved.
* Fix direct-spirv-emit output.
* Update to latest version of spirv headers and spirv-tools.
* Upgrade submodule version of glslang in external.
* Add fPIC to build options of slang-spirv-tools
* WIP adding support for InterlockedAddFp32
* Upgrade slang-binaries to have new glslang.
* Fix issues with Windows slang-glslang binaries, via update of slang-binaries used.
* WIP - atomicAdd. This solution can't work as we can't do (float*) in glsl.
* WIP on atomic float ops.
* Added checking for multiple decls that takes into account __target_intrinsic and __specialized_for_target.
First pass impl of atomic add on float for glsl.
* Split __atomicAdd so extensions are applied appropriately.
* Made Dxc/Fxc support includes.
Use HLSL prelude to pass the path to nvapi
Added -nv-api-path
* Refactor around IncludeHandler and impl of IncludeSystem
* slang-include-handler -> slang-include-system
Have IncludeHandler/Impl defined in slang-preprocessor
* Small comment improvements.
* Document atomic float add addition in target-compatibility.md.
* CUDA float atomic support on RWByteAddressBuffer.
* Add atomic-float-byte-address-buffer-cross.slang
* Removed inappropriate-once.slang - the test is no longer valid when a file is loaded and has a unique identity by default. A test could be made, but would require an API call to create the file (so no unique id).
Improved handling of loadFile - uses uniqueId if has one.
* Work around for testing target overlaps - to avoid exceptions on adding targets.
Simplify PathInfo setup.
Modify single-target-intrinsic.slang - it no longer failed because there were no longer multiple definitions for the same target.
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix a preprocessor bug affecting X-macros
Fixes #1435
This bug exhibited as nondeterministic output from the preprocessor in release builds, but using a debug build it was narrowed down to a use-after-free issue.
The core problem is subtle, but relates to how we set up the linked list that represents the "busy" status of macros in a particular expansion environment.
Consider this scenario:
```hlsl
X(A)
```
The flow we expect from the preprocessor is something like:
1. Read the `X` token in `X(A)` and recognize the start of a function-like macro invocation. Create an expansion environment for `X`, with the global environment as a parent, read in the arguments (just `A`), and push that expansion onto the stack.
2. Read the `M` token that starts the expansion of `M`, and recognize it as an invocation of the object-like macro representing the argument `M`. Create an expansion environment for the definition of `M` (which is just `A`), and push it onto the stack.
3. Read the token `A` from the expansion for the argument `M`, and recognize it as an invocation of the function-like macro `A`. Create an expansion environemnt for `A`, with the current environment as its parent, read in the arguments (just `0`), and push that expansion onto the stack.
4. Read the token `y` from the expansion for `A`, and recognize it as an invocation of the object-like macro representing the argument `y`. Create an expansion environment for the definition of `y` (which is just `0`) and push it onto the stack.
5. Read `0`.
6. Read a bunch of end-of-file tokens that cause all of these expansions to be popped.
That all looks fine as written, but the gotcha is that the input stream for the expansion in step (2) is only a single token (`A`), which means that during step (3) the current input stream at the time we *create* the macro expansion for `A` is at the end of its input, and by the time we've read in the macro arguments that expansion will have been popped.
The problem, then, is that the logic for setting up the stack of "busy" macros was being performed at the beginning of the expansion (the part referred to as "create an expansion" above), when it should only have been set up as part of pushing the xpansion onto the stack (since at that point we have a guarantee that the parent expansion cannot be popped until the child expansion has been).
The fix here is thus pretty simple: we already have distinct operations for `initializeMacroExpansion()` and `pushMacroExpansion()`, and I simply moved the logic for setting up the "busy" state from the former to the latter.
* fixup: typo
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix for a macro expansion bug
The work in #1177 added a notion of a macro being "busy" to prevent errors around recursively-defined macros:
#define BAR(X) BAR(0)
BAR(A) /* should yield BAR(0) and not infinite-loop */
The fix was to place an `isBusy` flag on each macro, setting it to `true` when an expansion of that macro gets pushed onto the stack of input streams, and back to `false` when the expansion gets popped from the stack of input streams.
That approach meant that we had to pre-expand macro arguments to avoid incorrectly treating a macro as busy for nested-but-not-recursive invocations:
#define NEG(X) (-X)
NEG(NEG(3)) // should expand to (-(-3)) and not (-NEG(3))
The subtle bug that arose with the `isBusy` flag is that the current preprocessor design doesn't always pop input streams when we might expect. For input like the following:
BAR(A) BAR(B)
The preprocessor can be in a state where the stack of input streams look like:
// top input stream:
BAR(X) => BAR(0)
----------------^
// bottom input stream
BAR(A) BAR(B)
------^
That is, the first macro expansion is still "open," even though it is at the end of its input. When the preprocesor looks ahead and sees `BAR` as the next token and asks whether it should be expanded, the `isBusy` state on the BAR macro hasn't yet been unset, so expansion gets skipped.
Aside: it is completely reasonable to ask at this point whether we should just "fix" the behavior of not popping input streams that are at their end. We should consider doing that, but the current code goes to some lengths to preserve the current behavior and I do *not* recall why we had found it necessary. Any attempt to change that behavior should come along with lots of testing.
This change instead adds a different approach for tracking the busy-ness of macros that doesn't rely on mutable state in the macro, and thus works even without pre-expansion of macro arguments.
In the Slang preprocessor, macro names are always looked up in *environments*, where each environment maps names to macros, and has an option parent environment.
There is a global environment used for most cases, but when expanding a function-like macro we would create an "argument environment" for it that maps the parameter names to their argument tokens.
By expanding the environment type to include an (optional) field for a macro that is made "busy" by that environment, we can check if a macro is busy in a given environment by checking if the given macro has been associated with any of the environments on the chain of parent environments.
A function-like macro expansion could then attach the macro to the "argument environment" and automatically make itself busy for the purposes of expansion of its body.
To extend the same functionality to *all* macros, the "argument environment" was changes to an "expansion environment" that always gets used for a macro expansion and always has the identity of the macro attached.
Because the arguments to a function-like macro have their own environment for expansion that bypasses the argument/expansion environment of the function-like macro, the macro will show as busy in its own body, but not in the expansion of its arguments. Thus the pre-expansion of macro arguments is not needed with this change.
Aside: it might not be clear how this design avoids the problem of the unpopped input streams that aren't at their end. The answer is that the "current" environment for the preprocessor is already taken as the environment of the top-most input stream that is *not at its end*. This means that the new test for busy-ness benefits from the existing logic that was in place to deal with non popping input streams as soon as then end. (This is not to say that the current input-stream behavior isn't questionable)
This change includes a new test case for the behavior that was broken, and expands the test case from #1177 to also test object-like macros.
* Fix to handle the mutually-recursive case
The revised "busy" logic was unable to handle a mutually-recursive macro like:
#define ABC XYZ
#define XYZ ABC
This change restores the ability to handle mutually recursive cases, and makes sure that we test that case.
The crux of the fix relies on splitting the environment and busy-macro tracking into more separate data structures.
Rather than the list of environments directly trakcing busy-ness via the chain of parent environments, an environment now stores a separate linked list of macros that should be considered busy in that environment.
Decoupling the two lists allows for an important change: when expanding an ordinary macro (either object-like or function-like, but *not* a function argument) the parent *environment* comes from the point where the macro was defined (this is required for lookup to make sense), but the parent list of *busy macros* comes from the current input stream at the point where expansion takes place. That change ensures that non-argument macros always properly "stack up" the list of busy macros.
|
| |
|
|
|
|
|
| |
* First pass fix of macro expansion logic to stop recursive application (causting a recursive loop), whilst also allowing application on parameters to a macro.
* Added recursive-macro test.
Fixed macro application example.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* A more convoluted #pragma once file identity test, using relative paths.
* Fix bug with passing - to slang as a command line option causes a crash.
Ability to set file-system to use on command line.
#pragma once tests try with 'normal' and 'read-file' only versions
* OSFileSystem -> OSFileSystemExt
LoadFileOSFileSystem -> OSFileSystem
Implemented OSFileSystem like OSFileSystemExt as as singleton.
Fixes to comments.
|
| |
|
|
|
|
|
|
|
|
| |
* Fix warnings from visual studio due to coercion losing data.
* Removed searchDirectories from FrontEndCompileRequest and use the one in Linkage as that is the one that is changed via Slang API.
* * Add searchPaths back to FrontEndRequest
* Add comments to explain the issue
* Add a test to check include paths
|
| |
|
|
|
|
|
|
|
| |
* Ignore expression if hit #if when skipping.
* Add test for #if parsing is ok
* * Use SkipToEndOfLine
* Improve comments slightly
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* * Fix memory bug around expanding va_args - needed buffer to have space for terminating 0
* Fix problem with FileWriter defaults being globals, as memory they allocate, will only be freed after return from main - work around by making StdWriters RefObject derived, and kept in scope such the writers are destroyed before checks for leaks is found
* Added SimplifyPathAndHash mode for CacheFileSystem - will simplify the path and see if simplified path is in cache before reading file (limiting amout of underlying file requests)
* * Added calcReplaceChar
* Renamed DefaultFileSystem to OSFileSystem
* Made OSFileSystem convert windows \ to / on linux
* Simplified logic for caching in CacheFileSystem.
* Added pragma-once-c to add extra test, but also so there is an 'include' directory in preprocessor tests.
* Small fixes in pragma once test.
* Simplified cache handling path, so that paths/simplified paths area always added.
* Improve naming of methods for different caches.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
* * Added COMMAND_LINE_SIMPLE test type
* Made how spawning works controllable by paramter/type SpawnType
* Made break-outside-loop and global-uniform run command line slangc
* calcRelativePath -> calcCombinedPath
* Add 64 bit version of GetHash.
* Add support for Hash based mode for CacheFileSystem.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Refactor of path handling.
* Added PathInfo
* Changed ISlangFileSystem - such that has separate concepts of reading a file, getting a relative path and getting a canonical path
* Added support for getting a canonical path for windows/linux
* Made maps/testing around canonicalPaths
* User output remains around 'foundPath' - which is the same as before
* Small improvements around PathInfo
* Added a type and make constructors to make clear the different 'path' uses
* Fixed bug in findViewRecursively
* Checking and reporting for ignored #pragma once.
* Removed SLANG_PATH_TYPE_NONE as doesn't serve any useful purpose.
* Improve comments in slang.h aroung ISlangFileSystem
* Remove the need for <windows.h> in slang-io.cpp
* Ran premake5.
* Improvements and fixes around PathInfo.
* Fix typo on linix GetCanonical
* Make the ISlangFileSystem the same as before, and ISlangFileSystem contain the new methods.
Internally it always uses the ISlangFileSystemExt, and will wrap a ISlangFileSystem with WrapFileSystem, if it is determined (via queryInterface) that it doesn't implement the full interface.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Improve diagnostic messages for function redefinition
The front-end was using internal "not implemented" errors instead of friendly user-facing errors to handle:
* Redefinition of a function (same signature and both have bodies)
* Multiple function declarations/definitions with the same parameter signature, but differnet return types
This change simply turns both of these into reasonably friendly errors that explain what went wrong and point to the previous definition/declaration as appropriate.
* Add support for detecting #pragma directives and handling them
The logic here mirrors what was set up for preprocessor directives, just for "sub-directives" in this case.
The only case here is the default one, which now reports a warning for directives we don't understand.
* Add basic support for #pragma once
Fixes #494
The approach here is simplistic in the extreme. When we see a `#pragma once` directive, we put the current file path (the location of the `#pragma` directive, as reported by our source manager) into a set, and then any paths in that set are ignored by subsequent `#include` directives.
This should work for simple cases of `#pragma once`, but it is likely to fail in a variety of cases because our filesystem layer currently makes no attempt to normalize/canonicalize paths. Improving the robustness of the solution is left to future work.
This change includes a simple test case to confirm that a second `#include` of a file with a `#pragma once` is successfully ignored.
|
| |
|
|
|
| |
Resolves #310
The behavior was fixed in #484, but that change didn't add test cases to cover the new functionality.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Fix handling of errors in imported modules
- If a semantic error is detected in an imported module, then don't try to generate IR code for it
- Also, if a module (transitively) imports itself, then report that as an error
- The way I'm checking for this is a bit hacky (I'm adding the module to the map of loaded modules, but in an "unfinished" state, and then using that unfinished state to detect the import of a module already being imported).
This isn't a 100% complete solution for any of the related problems, but it improves the user experience for the common case.
* Remove #import test.
The feature is slated to be removed, so it isn't worth fixing up this test case.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
* Preprocessor: fix `undef` and redefinition
The logic for `undef` directives was failing to suppress macro expansion when reading the name to un-define, and so it wasn't actually working at all. We didn't notice this because we didn't have a test case, and users hadn't tried it.
The logic for `define` had a similar bug, which meant that any attempt to define an already-defined macro would fail with a cryptic error, rather than raising the intended warning.
Test cases have been added for both issues, along with the fixes.
* fixup: add expected output for tests added
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixes #24
So far the code has used a representation for source locations that is heavy-weight, but typical of research or hobby compilers: a `struct` type containing a line number and a (heap-allocated) string.
This is actually very convenient for debugging, but it means that any data structure that might contain a source location needs careful memory management (because of those strings) and has a tendency to bloat.
The new represnetation is that a source location is just a pointer-sized integer.
In the simplest mental model, you can think of this as just counting every byte of source text that is passed in, and using those to name locations.
Finding the path and line number that corresponds to a location involves a lookup step, but we can arrange to store all the files in an array sorted by their start locations, and do a binary search.
Finding line numbers inside a file is similarly fast (one you pay a one-time cost to build an array of starting offsets for lines).
More advanced compilers like clang actually go further and create a unique range of source locations to represent a file each time it gets included, so that they can track the include stack and reproduce it in diagnostic messages.
I'm not doing anything that clever here.
|
| |
|
|
|
|
| |
- Allow a code-generation target of `NONE` in order to suppress ordinary output in test cases where we don't care about the actual output (just pass/fail result)
- Add explicit `location` layout qualifiers to intermediate vertex-to-fragment variables in GLSL test cases for rendering, to work around apparent Intel driver bugs.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
With this change, there is now a meaningful semantic difference between `__import` and `#import`.
An `__import` compiles the target file in a fresh environment, only providing it any macro definitions passed via command line or API. Any macros defined in the imported file are not made visible at the import site. One can think of an `__import` as a bit like `using namespace` in C++.
A `#import` will tokenize the input in the same preprocessor environment as the importing file, and any macros defined along the way will be visible in the parent file.
It is a *bit* like a `#include` with two big differences:
- The imported code is always parsed as Slang, and as its own module with default flags, etc. (so semantic checks are on even if we are in "rewriter" mode). It is pulled into the outer namespace just as for `__import`.
- A given file will only get `#import`ed once for a translation unit, so it behaves a bit like there is an implicit `#pragma once` in the target file
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This includes a bunch of related changes:
- `slang-test`
- Add a notion of an "output mode" that specifies whether we output to console (the default), or invoke the apprpriate AppVeyor command to update test status
- Add a notion of test categories, so that tests can be tagged with categories, and then we can invoke only those tets in a given category, or choose to *exclude* tests with specific categories
- Allow the `OSProcessSpawner` to look up an executable by "path" (meaning a full path is expected) or by "name" (meaning it should be allowed to look in the current directory, `PATH` environment variable, etc.). This was important to make sure that I can run `appveyor` without having to know its absolute path.
- AppVeyor configuration
- Change badge to reflect new build account for organization (rather than a single-user account)
- Remove attempt to set AppVeyor build version in a clever way, since it breaks links from GitHub to AppVeyor
- Change order or configurations in the build matrix to front-load the Release build (which has the main tests)
- Turn on `fast_finish` flag so we don't have to wait as long for failed builds
- Turn on `parallel` builds
- Set `verbosity: minimal` to avoid getting build spew about Xamarin stuff I'm not using
- Add custom `test_script` to invoke `test.bat`
- Sets the test category based on teh build configuration, so we don't run the full test suite on every input.
- `test.bat`
- Allow for `-platform` and `-configuration` arguments
- Rewrute a platform of `Win32` over to `x86` to match how the output directories are named
- Futz around with how the directories are being passed along to work around annoying `.bat` file quoting behavior (I still don't get how batch files work)
- Tests
- Mark a bunch of tests as `smoke` tests
- Mark the relevant tests as `render` tests
(these get filtered out for AppVeyor builds)
|
| |
|
|
| |
This also serves as a regression test for the recent preprocessor bug fix.
|
| |
|
|
| |
Many of the existing test cases were being skipped on accident, because their file names used `.spire` and the test tool was now looking for `.slang`
|
| |
|