<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/preprocessor.h, 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>2019-05-31T21:20:37+00:00</updated>
<entry>
<title>Use slang- prefix on slang compiler and core source (#973)</title>
<updated>2019-05-31T21:20:37+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-05-31T21:20:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f'/>
<id>urn:sha1:6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f</id>
<content type='text'>
* Prefixing source files in source/slang with slang-

* Prefix source in source/slang with slang- prefix.

* Rename core source files with slang- prefix.

* Update project files.

* Fix problems from automatic merge.
</content>
</entry>
<entry>
<title>Split front- and back-ends (#846)</title>
<updated>2019-02-15T17:08:19+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2019-02-15T17:08:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=a3fd4e2bc40cfc77db953b14744c30e7a18e7c1d'/>
<id>urn:sha1:a3fd4e2bc40cfc77db953b14744c30e7a18e7c1d</id>
<content type='text'>
* Split front- and back-ends

This change is a major refactor of several of the types that provide the behind-the-scenes implementation of the public C API.
The goal of this refactor is primarily to allow for future API services that let the user operate both the front- and back-ends of the compiler in a more complex fashion.
For example, as user should be able to compile a bunch of source code into modules, look up types, functions, etc. in those modules, specialize generic types/functions to the types they've looked up, and then finally request target code to be gernerated for specialized entry points.
The back-end code generation they trigger should re-use the front-end compilation work (parsing, semantic checking, IR generation) that was already performed.

The most visible change is that `CompileRequest` has been split up into several smaller types that take responsibility for parts of what it did:

* The `Linkage` type owns the storage for `import`ed modules, and well as the `TargetRequest`s that represent code-generation targets. The intention is that an application could use a single `Linkage` for the duration of its runtime (so long as it was okay with the memory usage), so that each `import`ed module only gets loaded once. For now, this type needs to manage the search paths, file system, and source manager, because of its responsibility for loading files.

* A `FrontEndCompileRequest` owns the stuff related to parsing, semantic checking, and initial IR generation. This most notably includes the `TranslationUnitRequest`s and the `FrontEndEntryPointRequest`s (which used to be just `EntryPointRequest`s). It's main job is to produce AST and IR modules for each translation unit, and to find and validate the entry points. The front-end request does *not* interact with generic arguments for global or entry-point generic parameters.

* The main output of both `import` operations and front-end translation units is the `Module` type, which is just a simple container for both the AST module (to service the reflection/layout APIs, and also for semantic checking of code that `import`s the module) and the IR module (for linking and code generation). This type captures the commonalities between the old `LoadedModule` (which is now just an alias for `Module`) and `TranslationUnitRequest` (which now owns a `Module`).

* The secondary output of front-end compilation is a `Program`, which comprises a list of referenced `Module`s and validated `EntryPoint`s that will be used together. Layout and code generation both need a `Program` to tell them what modules and entry points will be used together (we don't want to just code-gen everythin that has ever been loaded into the linakge). The `Program`s created by the front-end do not include generic arguments, so they may provide incomplete layout information and/or be unsuitable for code generation.

* A `BackEndCompileRequest` owns stuff related to turning a `Program` into output kernels for the targets of a `Linkage`. Most of the data it owns beyond the `Program` to be compiled is minor, so this is a good candidate for demotion from a heap-allocated object to just a `struct` of options that gets passed around.

* The `CompileRequestBase` type is an attempt to wrap up the common functionality of both front-end and back-end compile requests. Most of it is just exposing the availability of a linkage and `DiagnosticSink`, so this type is a good candidate for subsequent removal. The main interesting thing it has is the flags related to dumping and validation of IR, so there is probably a good refactoring still to be made around deciding how options should be handled going forward.

* Behind the scenes, the `Program` type is set up to handle some level of on-line compilation and layout work. The `Program` knows the `Linkage` it belongs to, and allows for a `TargetProgram` to be looked up based on a specific `TargetRequest`. A `TargetProgram` then allows layout information and compiled kernel code to be asked for on-demand, in order to support eventual "live" compilation scenarios.

* The `EndToEndCompileRequest` type is a composition/coordination type that replaces the old `CompileRequest` in a way that uses the services of the various other types. It owns a few pieces of state that only make sense in the context of an end-to-end compile (e.g., there is really no way to "pass through" code when the front- and back-ends are run separately) or a command-line compile (everything to do with specifying output paths for files is really just for the benefit of `slangc`, and might even be moved there over time).

* One important detail is that the `EndToEndCompilRequest` owns all of the string-based generic arguments for both global and entry-point generic parameters. The logic in `check.cpp` for dealing with those arguments has been heavily refactored to separate out the parsings steps that are specific to end-to-end compilation with string-based type arguments, and the semantic checking  steps that result in a specialized `Program` (which can be exposed through new APIs that aren't tied to end-to-end compilation).

It is perhaps not surprising that this change had a lot of consequences, so I'll briefly run over some of the main categories of changes required:

* I changed the way that global generic arguments are passed via API (use `spSetGlobalGenericArgs` instead of the generic arguments for `spAddEntryPointEx`, which are not just for entry-point generics), which has been a change that we've needed for a long time. This is technically a breaking API change, although we should have very few client applications that care about it.

* A bunch of places that used to take "big" objects like `CompileRequest` now just take the sub-pieces they care about (e.g., a function might have only needed a `Linkage` and a `DiagnosticSink`). This makes many subroutines or "context" struct types more generally useful, at the cost of taking more parameters.

* In a few cases the conceptually clean separation of the layers breaks down (often for edge-case or compatibility features), and so we may pass along additional objects that are allowed to be null, but are used when present. A big example of this is how the back-end code generation routines accept an `EndToEndCompileRequest` that is optional, and only used to check whether "pass through" compilation is needed. We should probably look into cleaning this kind of logic up over time so that we don't need to violate the apparent separation of phases of compilation.

* In cases where separation of layers was being broken for the sake of GLSL features, I went ahead and ripped them out, since all of that should be dead code anyway.

* In many cases I increased the encapsulation of data in the core types to help track down use sites and make sure they are following invariants better.

* In cases where code was doing, e.g., `context-&gt;shared-&gt;compileRequest-&gt;session-&gt;getThing()` I have tried to introduce convenience routines so that the usage site is just `context-&gt;getThing()` to improve encapsulation and allow changes to be made more easily going forward.

* The `noteInternalErrorLoc` functionality was moved off of the compile request and into `DiagnosticSink`, since that is the one type you can rely on having around when you want to note an internal error. We may consider going forward if (and how) it should reset the counter used for noting locations on internal errors.

* A few APIs now take `DiagnosticSink*` arguments where they didn't before, and as a result some public APIs need to create `DiagnosticSink`s to pass in, before going ahead and ignoring the messages. In the future there should be variations of these APIs that accept an `ISlangBlob**` parameter for the output.

* fixup: missing include for compilers with accurate template checking (non-VS)

* fixup: review feedback
</content>
</entry>
<entry>
<title>Feature/view path (#824)</title>
<updated>2019-02-04T22:30:51+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-02-04T22:30:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=9b80537bc0272a9caf93f146d8964d9bdd4a407e'/>
<id>urn:sha1:9b80537bc0272a9caf93f146d8964d9bdd4a407e</id>
<content type='text'>
* Use 'is' over 'as' where appropriate.

* dynamic_cast -&gt; dynamicCast

* Replace 'dynamicCast' with 'as' where has no change in behavior/ambiguity.

* Replace dynamicCast with as where doesn't change behavior/non ambiguous.

* Keep a per view path to the file loaded - such that diagnostic messages always display the path to the requested file.

* Add simplifyPath to ISlangFileSystemExt
Simplify (if possible) paths that are set on SourceFile and SourcView - doing so makes reading paths simpler.

* Fix small typo.

* Improve documentation in source for getFileUniqueIdentity

* Fix override warning.
</content>
</entry>
<entry>
<title>Feature/include refactor (#675)</title>
<updated>2018-10-16T22:49:11+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2018-10-16T22:49:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=3e74d39f24fdfaa547ce900be177863e2bfe2dea'/>
<id>urn:sha1:3e74d39f24fdfaa547ce900be177863e2bfe2dea</id>
<content type='text'>
* 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 &lt;windows.h&gt; 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.
</content>
</entry>
<entry>
<title>Add support for "blobs" and a file-system callback (#596)</title>
<updated>2018-06-14T18:56:31+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2018-06-14T18:56:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=e66d66b88e1c6ef8499708952fcbe3ba873f6e4c'/>
<id>urn:sha1:e66d66b88e1c6ef8499708952fcbe3ba873f6e4c</id>
<content type='text'>
* Add support for "blobs" and a file-system callback

The most obvious change here is that the Slang header now includes a few COM-style interfaces that can be used for communication between the application and compiler. In order to support the declaration of COM-like interfaces, several platform-detection macros were lifted out of `slang-defines.h` and into the public `slang.h` header. As it exists right now, this change makes the Slang API C++-only, but a C-compatible version can be defined later with the help of lots of macros (and/or something like an IDL compiler).

The two big interfaces introduced are:

* The `ISlangBlob` interface, which is compatible with `ID3DBlob`, `IDxcBlob`, etc. This is used to pass ownership of source/compiled code across the API boundary without copies. New versions of various entry points have been added to allow passing blobs: e.g., `spAddTranslationUnitSourceBlob` and `spGetEntryPointCodeBlob`.

* The `ISlangFileSystem` interface, which is used to allow applications to intercept any attempt by the Slang compiler to load a file (input source files, include files, etc.). This is *not* the same as the `IDxcIncludeHandler` interface, because it assumes UTF-8 encoded path names, instead of the 16-bit encoding that dxc/Windows prefer. It is also not very similar to `ID3DInclude` as used by fxc, because this callback interface is *not* responsible for handling the search through include paths, etc. - it is just a file-system abstraction layer.

Internally, a few different parts of the compiler were changed to either store data in blob form all the time, or to be able to synthesize a blob on-demand. Because our internal `String` type is a reference-counted copy-on-write type, using a `SlangStringBlob` to hold string data should achieve transfer of ownership back to the application without extraneous copies. There is plenty of room to clean up the architecture of some of these internal pieces if they *know* that their data will end up in a blob.

The existing Slang testing doesn't touch any of the APIs introduced here, so they can only confirm that existing functionality hasn't been broken. The new ability to return code blobs has been tested by integration of that feature into Falcor, but there has been zero testing of the ability to pass *in* source code as blobs, and the ability to hook file loading. Future changes will need to add test coverage for the new features.

* fixup: define SLANG_NO_THROW for non-Windows builds

* fixup: header copy-paste error caught by clang/gcc

* Cleanup: return reference-counted objects via output parameters

Returning a reference-counted object through the API as a raw pointer creates challenges.
The "obvious" answer is that the returned pointer should have an added reference (it is returned at "+1"), and the caller is responsible for releasing that reference. This makes sense when using raw pointers on the calling side:

```c++
IFoo* foo = spGetFoo(...);
...
foo-&gt;Release();
```

However, as soon as smart pointers start getting involved (to handle releasing reference counts when we are done with things), the picture gets more complicated:

```c++
MySmartPtr&lt;IFoo&gt; foo = spGetFoo(...);
...
```

The intention of code like that is that `foo` gets released when the smart pointer goes out of scope, but this probably doesn't happen with most smart pointer implementations. If the `MySmartPtr` constructor that takes a raw pointer retains it, then the destructor will only release *that* reference, and so the object will leak.

It is possible that the user will have a smart pointer type where the constructor that takes a raw pointer doesn't retain it, but in general such types introduce the potential for errors of their own, and no matter what the Slang API shouldn't go in assuming any particular policy.

This change makes it so that any reference-counted objects that are logically returned from a call are returned through output pointers. This design makes the leak-free cases easy (enough) to implement with raw pointers or smart pointers:

```c++
// raw pointer
IFoo* foo = nullptr;
spGetFoo(..., &amp;foo);
...
foo-&gt;Release();

// smart pointer
MySmartPtr&lt;IFoo&gt; foo;
spGetFoo(..., foo.writeableRef());
...
```

The only assumption here is that any COM smart-pointer type needs to provide an operation like `writableRef` that is suitable for using that pointer as an output parameter. Given that COM *loves* output parameters, this seems like a safe assumption (at the very least, anybody who interacts with COM would be used to this convention).

Future changes might introduce inline convenience methods for various operations that return results more directly, possibly by introducing a minimal smart-pointer type in the `slang.h` header (without prescribing that clients must use it...).

* fixup: another error caught by gcc/clang
</content>
</entry>
<entry>
<title>Make source location lightweight</title>
<updated>2017-08-10T20:05:04+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-08-09T19:57:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=a5a436c4783fb75a0d089a6483219c06db91f593'/>
<id>urn:sha1:a5a436c4783fb75a0d089a6483219c06db91f593</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Major naming overhaul:</title>
<updated>2017-08-09T17:23:09+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-08-09T17:13:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=695c2700de54a5fec72ce7214c137a1dc3a02d7b'/>
<id>urn:sha1:695c2700de54a5fec72ce7214c137a1dc3a02d7b</id>
<content type='text'>
- `ExpressionSyntaxNode` becomes `Expr`
- `StatementSyntaxNode` becomes `Stmt`
- `StructSyntaxNode` becomes `StructDecl`
- `ProgramSyntaxNode` becomes `ModuleDecl`
- `ExpressionType` becomes `Type`
  - Existing fields names `Type` become `type`
  - There might be some collateral damage here if there were, e.g., `enum`s named `Type`, but I can live with that for now and fix those up as a I see them
</content>
</entry>
<entry>
<title>Check for re-import at translation-unit level</title>
<updated>2017-06-26T19:17:49+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-06-26T17:52:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=f6cb66feab3439f41ca87cb307f69b49654883ab'/>
<id>urn:sha1:f6cb66feab3439f41ca87cb307f69b49654883ab</id>
<content type='text'>
Previously the code checked for a duplicate `#import` using a data structure attached to the compile request, but this would fail for nested imports.
It also wouldn't work for a combination of `#import` and `__import`.

This change makes it so that we instead track a set of already-imported modules in the semantic checking visitor, which is instantiated once per translation unit.
We also key this set on the actual module (AST) imported, rather than on path/name/whatever, so hopefully it will be robust to the same thing getting imported multiple ways.
</content>
</entry>
<entry>
<title>Replace "auto-import" with `#import`</title>
<updated>2017-06-26T19:06:54+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-06-26T16:32:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7d3bfe403362b294cc2a1f2607d51dfcd447aafd'/>
<id>urn:sha1:7d3bfe403362b294cc2a1f2607d51dfcd447aafd</id>
<content type='text'>
Right now `#import` only differs from `#include` in that it takes a string literal for a file name instead of a raw identifier (to which `.slang` gets appended).

The next step is to make `#import` respect preprocessor state, while `__import` doesn't.
</content>
</entry>
<entry>
<title>Overhaul handling of entry points and translation units.</title>
<updated>2017-06-20T18:54:35+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoley@nvidia.com</email>
</author>
<published>2017-06-20T15:11:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=327f2b7ec50a7480b458d6d3ba8e2ca7fcdb8498'/>
<id>urn:sha1:327f2b7ec50a7480b458d6d3ba8e2ca7fcdb8498</id>
<content type='text'>
The main user-visible change here is that instead of `spAddTranslationUnitEntryPoint` we have `spAddEntryPoint`, to reflect that the list of entry points is "global" to a compile request.
As a result, `spGetEntryPointSource` now only needs the entry point index, and not the translation unit index.

There are a bunch more behind-the-scenes changes, though, reflecting a streamlining of the concepts related to compilation into a smaller number of classes.
Now there is:

- `Session` (unchanged) to manage the lifetimes of shared stuff like the stdlib

- `CompileRequest` (merges in `CompileOptions`) to handle all the lifetime related to a single invocation of the compiler

- `TranslationUnitRequest` (merges `TranslationUnitOptions`, `CompileUnit`) to represent a single translation unit ("module") that the user is trying to compile. This is a single file for HLSL/GLSL, but can be multiple files for Slang.

- `EntryPointRequest` (merges `EntryPointOption` and a bit of `EntryPointResult`) to track a single entry point that the user is asking to compile (that entry point always comes from a single translation unit)

A lot of functions used to take some combination of these and end up with really long signatures.
I've given most of the objects "parent" pointers so that they can get back to all the context they need, so most functions don't need as many parameters.

It may eventually be important to tease these apart again, in particular:

- The code-generation side of things (the `*Result` types) might need to be pulled out in case we want to codegen multiple times from the same AST

- Similarly, the layout stuff may also need to be pulled out, in case we want to lay things out multiple times with different rules.
</content>
</entry>
</feed>
