Name Date Size #Lines LOC

..--

.github/H25-Apr-2025-689610

External/H25-Apr-2025-7873

SPIRV/H25-Apr-2025-31,59924,968

StandAlone/H25-Apr-2025-3,0132,284

Test/H25-Apr-2025-575,682554,364

build_overrides/H25-Apr-2025-117109

glslang/H25-Apr-2025-101,29376,576

gtests/H25-Apr-2025-5,9644,374

kokoro/H25-Apr-2025-1,053617

ndk_test/H25-Apr-2025-599

.clang-formatH A D25-Apr-2025379 1413

.gitattributesH A D25-Apr-2025523 1815

.gitignoreH A D25-Apr-2025252 2623

.gnH A D25-Apr-20251.7 KiB4037

.mailmapH A D25-Apr-2025219 43

BUILD.gnH A D25-Apr-202511 KiB355320

CHANGES.mdH A D25-Apr-202512 KiB337275

CMakeLists.txtH A D25-Apr-202514.8 KiB401350

CODE_OF_CONDUCT.mdH A D25-Apr-2025280 21

DEPSH A D25-Apr-20252.8 KiB8372

LICENSE.txtH A D25-Apr-202553.4 KiB1,017836

README-spirv-remap.txtH A D25-Apr-20255.1 KiB137100

README.mdH A D25-Apr-202520.1 KiB541391

SECURITY.mdH A D25-Apr-2025319 74

_config.ymlH A D25-Apr-202527 21

build_info.h.tmplH A D25-Apr-20252.9 KiB6355

build_info.pyH A D25-Apr-20258 KiB245172

gen_extension_headers.pyH A D25-Apr-20253.6 KiB9964

known_good.jsonH A D25-Apr-2025668 2625

known_good_khr.jsonH A D25-Apr-2025632 2625

license-checker.cfgH A D25-Apr-20251.7 KiB6156

parse_version.cmakeH A D25-Apr-20251.9 KiB4240

standalone.gclientH A D25-Apr-20251.7 KiB4341

update_glslang_sources.pyH A D25-Apr-20254.9 KiB153101

README-spirv-remap.txt

1
2VERSION
3--------------------------------------------------------------------------------
4spirv-remap 0.97
5
6INTRO:
7--------------------------------------------------------------------------------
8spirv-remap is a utility to improve compression of SPIR-V binary files via
9entropy reduction, plus optional stripping of debug information and
10load/store optimization.  It transforms SPIR-V to SPIR-V, remapping IDs.  The
11resulting modules have an increased ID range (IDs are not as tightly packed
12around zero), but will compress better when multiple modules are compressed
13together, since compressor's dictionary can find better cross module
14commonality.
15
16Remapping is accomplished via canonicalization.  Thus, modules can be
17compressed one at a time with no loss of quality relative to operating on
18many modules at once.  The command line tool operates on multiple modules
19only in the trivial repetition sense, for ease of use.  The remapper API
20only accepts a single module at a time.
21
22There are two modes of use: command line, and a C++11 API.  Both are
23described below.
24
25spirv-remap is currently in an alpha state.  Although there are no known
26remapping defects, it has only been exercised on one real world game shader
27workload.
28
29
30FEEDBACK
31---------------------------------------------------------------------------------
32Report defects, enhancement requests, code improvements, etc by creating
33issues in the glslang repository at https://github.com/KhronosGroup/glslang
34
35COMMAND LINE USAGE:
36--------------------------------------------------------------------------------
37Examples are given with a verbosity of one (-v), but more verbosity can be
38had via -vv, -vvv, etc, or an integer parameter to --verbose, such as
39"--verbose 4".  With no verbosity, the command is silent and returns 0 on
40success, and a positive integer error on failure.
41
42Pre-built binaries for several OSs are available.  Examples presented are
43for Linux.  Command line arguments can be provided in any order.
44
451. Basic ID remapping
46
47Perform ID remapping on all shaders in "*.spv", writing new files with
48the same basenames to /tmp/out_dir.
49
50  spirv-remap -v --map all --input *.spv --output /tmp/out_dir
51
522. Perform all possible size reductions
53
54  spirv-remap-linux-64 -v --do-everything --input *.spv --output /tmp/out_dir
55
56Note that --do-everything is a synonym for:
57
58  --map all --dce all --opt all --strip all
59
60API USAGE:
61--------------------------------------------------------------------------------
62
63The public interface to the remapper is defined in SPIRV/SPVRemapper.h as follows:
64
65namespace spv {
66
67class spirvbin_t
68{
69public:
70   enum Options { ... };
71   spirvbin_t(int verbose = 0);  // construct
72
73   // remap an existing binary in memory
74   void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
75
76   // Type for error/log handler functions
77   typedef std::function<void(const std::string&)> errorfn_t;
78   typedef std::function<void(const std::string&)> logfn_t;
79
80   // Register error/log handling functions (can be c/c++ fn, lambda fn, or functor)
81   static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
82   static void registerLogHandler(logfn_t handler)     { logHandler   = handler; }
83};
84
85} // namespace spv
86
87The class definition is in SPVRemapper.cpp.
88
89remap() accepts an std::vector of SPIR-V words, modifies them per the
90request given in 'opts', and leaves the 'spv' container with the result.
91It is safe to instantiate one spirvbin_t per thread and process a different
92SPIR-V in each.
93
94The "opts" parameter to remap() accepts a bit mask of desired remapping
95options.  See REMAPPING AND OPTIMIZATION OPTIONS.
96
97On error, the function supplied to registerErrorHandler() will be invoked.
98This can be a standard C/C++ function, a lambda function, or a functor.
99The default handler simply calls exit(5); The error handler is a static
100member, so need only be set up once, not once per spirvbin_t instance.
101
102Log messages are supplied to registerLogHandler().  By default, log
103messages are eaten silently.  The log handler is also a static member.
104
105BUILD DEPENDENCIES:
106--------------------------------------------------------------------------------
107 1. C++11 compatible compiler
108 2. cmake
109 3. glslang
110
111
112BUILDING
113--------------------------------------------------------------------------------
114The standalone remapper is built along side glslang through its
115normal build process.
116
117
118REMAPPING AND OPTIMIZATION OPTIONS
119--------------------------------------------------------------------------------
120API:
121   These are bits defined under spv::spirvbin_t::, and can be
122   bitwise or-ed together as desired.
123
124   MAP_TYPES      = canonicalize type IDs
125   MAP_NAMES      = canonicalize named data
126   MAP_FUNCS      = canonicalize function bodies
127   DCE_FUNCS      = remove dead functions
128   DCE_VARS       = remove dead variables
129   DCE_TYPES      = remove dead types
130   OPT_LOADSTORE  = optimize unneeded load/stores
131   MAP_ALL        = (MAP_TYPES | MAP_NAMES | MAP_FUNCS)
132   DCE_ALL        = (DCE_FUNCS | DCE_VARS | DCE_TYPES)
133   OPT_ALL        = (OPT_LOADSTORE)
134   ALL_BUT_STRIP  = (MAP_ALL | DCE_ALL | OPT_ALL)
135   DO_EVERYTHING  = (STRIP | ALL_BUT_STRIP)
136
137

README.md

1![Continuous Integration](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_integration.yml/badge.svg)
2![Continuous Deployment](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_deployment.yml/badge.svg)
3[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/KhronosGroup/glslang/badge)](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/glslang)
4
5# News
6
71. Building glslang as a DLL or shared library is now possible and supported.
8
92. The `GenericCodeGen`, `MachineIndependent`, `OSDependent`, and `SPIRV` libraries have been integrated into the main `glslang` library. The old separate libraries have replaced with empty stubs for a temporary compatibility period, and they will be removed entirely in the future.
10
113. A new CMake `ENABLE_SPIRV` option has been added to control whether glslang is built with SPIR-V support. Its default value is `ON`.
12
134. `OGLCompiler` and `HLSL` stub libraries have been fully removed from the build.
14
15# Glslang Components and Status
16
17There are several components:
18
19### Reference Validator and GLSL/ESSL -> AST Front End
20
21An OpenGL GLSL and OpenGL|ES GLSL (ESSL) front-end for reference validation and translation of GLSL/ESSL into an internal abstract syntax tree (AST).
22
23**Status**: Virtually complete, with results carrying similar weight as the specifications.
24
25### HLSL -> AST Front End
26
27An HLSL front-end for translation of an approximation of HLSL to glslang's AST form.
28
29**Status**: Partially complete. Semantics are not reference quality and input is not validated.
30This is in contrast to the [DXC project](https://github.com/Microsoft/DirectXShaderCompiler), which receives a much larger investment and attempts to have definitive/reference-level semantics.
31
32See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
33
34### AST -> SPIR-V Back End
35
36Translates glslang's AST to the Khronos-specified SPIR-V intermediate language.
37
38**Status**: Virtually complete.
39
40### Reflector
41
42An API for getting reflection information from the AST, reflection types/variables/etc. from the HLL source (not the SPIR-V).
43
44**Status**: There is a large amount of functionality present, but no specification/goal to measure completeness against.  It is accurate for the input HLL and AST, but only approximate for what would later be emitted for SPIR-V.
45
46### Standalone Wrapper
47
48`glslang` is command-line tool for accessing the functionality above.
49
50Status: Complete.
51
52Tasks waiting to be done are documented as GitHub issues.
53
54## Other References
55
56Also see the Khronos landing page for glslang as a reference front end:
57
58https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
59
60The above page, while not kept up to date, includes additional information regarding glslang as a reference validator.
61
62# How to Use Glslang
63
64## Execution of Standalone Wrapper
65
66To use the standalone binary form, execute `glslang`, and it will print
67a usage statement.  Basic operation is to give it a file containing a shader,
68and it will print out warnings/errors and optionally an AST.
69
70The applied stage-specific rules are based on the file extension:
71* `.vert` for a vertex shader
72* `.tesc` for a tessellation control shader
73* `.tese` for a tessellation evaluation shader
74* `.geom` for a geometry shader
75* `.frag` for a fragment shader
76* `.comp` for a compute shader
77
78For ray tracing pipeline shaders:
79* `.rgen` for a ray generation shader
80* `.rint` for a ray intersection shader
81* `.rahit` for a ray any-hit shader
82* `.rchit` for a ray closest-hit shader
83* `.rmiss` for a ray miss shader
84* `.rcall` for a callable shader
85
86There is also a non-shader extension:
87* `.conf` for a configuration file of limits, see usage statement for example
88
89## Building (CMake)
90
91Instead of building manually, you can also download the binaries for your
92platform directly from the [main-tot release][main-tot-release] on GitHub.
93Those binaries are automatically uploaded by the buildbots after successful
94testing and they always reflect the current top of the tree of the main
95branch.
96
97### Dependencies
98
99* A C++17 compiler.
100  (For MSVS: use 2019 or later.)
101* [CMake][cmake]: for generating compilation targets.
102* make: _Linux_, ninja is an alternative, if configured.
103* [Python 3.x][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools and the 'External' subdirectory does not exist.)
104* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
105* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
106
107### Build steps
108
109The following steps assume a Bash shell. On Windows, that could be the Git Bash
110shell or some other shell of your choosing.
111
112#### 1) Check-Out this project
113
114```bash
115cd <parent of where you want glslang to be>
116git clone https://github.com/KhronosGroup/glslang.git
117```
118
119#### 2) Check-Out External Projects
120
121```bash
122./update_glslang_sources.py
123```
124
125#### 3) Configure
126
127Assume the source directory is `$SOURCE_DIR` and the build directory is `$BUILD_DIR`.
128CMake will create the `$BUILD_DIR` for the user if it doesn't exist.
129
130First change your working directory:
131```bash
132cd $SOURCE_DIR
133```
134
135For building on Linux:
136
137```bash
138cmake -B $BUILD_DIR -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
139# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo"
140```
141
142For building on Android:
143```bash
144cmake -B $BUILD_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_STL=c++_static -DANDROID_PLATFORM=android-24 -DCMAKE_SYSTEM_NAME=Android -DANDROID_TOOLCHAIN=clang -DANDROID_ARM_MODE=arm -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake
145# If on Windows will be -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_HOME%\prebuilt\windows-x86_64\bin\make.exe
146# -G is needed for building on Windows
147# -DANDROID_ABI can also be armeabi-v7a for 32 bit
148```
149
150For building on Windows:
151
152```bash
153cmake -B $BUILD_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
154# The CMAKE_INSTALL_PREFIX part is for testing (explained later).
155```
156
157Also, consider using `git config --global core.fileMode false` (or with `--local`) on Windows
158to prevent the addition of execution permission on files.
159
160#### 4) Build and Install
161
162```bash
163# for Linux:
164make -j4 install
165
166# for Windows:
167cmake --build . --config Release --target install
168# "Release" (for --config) could also be "Debug", "MinSizeRel", or "RelWithDebInfo"
169```
170
171If using MSVC, after running CMake to configure, use the
172Configuration Manager to check the `INSTALL` project.
173
174### Building (GN)
175
176glslang can also be built with the [GN build system](https://gn.googlesource.com/gn/).
177
178#### 1) Install `depot_tools`
179
180Download [depot_tools.zip](https://storage.googleapis.com/chrome-infra/depot_tools.zip),
181extract to a directory, and add this directory to your `PATH`.
182
183#### 2) Synchronize dependencies and generate build files
184
185This only needs to be done once after updating `glslang`.
186
187With the current directory set to your `glslang` checkout, type:
188
189```bash
190./update_glslang_sources.py
191gclient sync --gclientfile=standalone.gclient
192gn gen out/Default
193```
194
195#### 3) Build
196
197With the current directory set to your `glslang` checkout, type:
198
199```bash
200cd out/Default
201ninja
202```
203
204### If you need to change the GLSL grammar
205
206The grammar in `glslang/MachineIndependent/glslang.y` has to be recompiled with
207bison if it changes, the output files are committed to the repo to avoid every
208developer needing to have bison configured to compile the project when grammar
209changes are quite infrequent. For windows you can get binaries from
210[GnuWin32][bison-gnu-win32].
211
212The command to rebuild is:
213
214```bash
215bison --defines=MachineIndependent/glslang_tab.cpp.h
216      -t MachineIndependent/glslang.y
217      -o MachineIndependent/glslang_tab.cpp
218```
219
220The above command is also available in the bash script in `updateGrammar`,
221when executed from the glslang subdirectory of the glslang repository.
222
223### Building to WASM for the Web and Node
224### Building a standalone JS/WASM library for the Web and Node
225
226Use the steps in [Build Steps](#build-steps), with the following notes/exceptions:
227* `emsdk` needs to be present in your executable search path, *PATH* for
228  Bash-like environments:
229  + [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)
230* Wrap cmake call: `emcmake cmake`
231* Set `-DENABLE_OPT=OFF`.
232* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
233* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
234* To get a fully minimized build, make sure to use `brotli` to compress the .js
235  and .wasm files
236* Note that by default, Emscripten allocates a very small stack size, which may
237  cause stack overflows when compiling large shaders. Use the
238  [STACK_SIZE](https://emscripten.org/docs/tools_reference/settings_reference.html?highlight=environment#stack-size)
239  compiler setting to increase the stack size.
240
241Example:
242
243```sh
244emcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_JS=ON \
245    -DENABLE_HLSL=OFF -DENABLE_OPT=OFF ..
246```
247
248## Building glslang - Using vcpkg
249
250You can download and install glslang using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
251
252    git clone https://github.com/Microsoft/vcpkg.git
253    cd vcpkg
254    ./bootstrap-vcpkg.sh
255    ./vcpkg integrate install
256    ./vcpkg install glslang
257
258The glslang port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
259
260## Testing
261
262Right now, there are two test harnesses existing in glslang: one is [Google
263Test](gtests/), one is the [`runtests` script](Test/runtests). The former
264runs unit tests and single-shader single-threaded integration tests, while
265the latter runs multiple-shader linking tests and multi-threaded tests.
266
267Tests may erroneously fail or pass if using `ALLOW_EXTERNAL_SPIRV_TOOLS` with
268any commit other than the one specified in `known_good.json`.
269
270### Running tests
271
272The [`runtests` script](Test/runtests) requires compiled binaries to be
273installed into `$BUILD_DIR/install`. Please make sure you have supplied the
274correct configuration to CMake (using `-DCMAKE_INSTALL_PREFIX`) when building;
275otherwise, you may want to modify the path in the `runtests` script.
276
277Running Google Test-backed tests:
278
279```bash
280cd $BUILD_DIR
281
282# for Linux:
283ctest
284
285# for Windows:
286ctest -C {Debug|Release|RelWithDebInfo|MinSizeRel}
287
288# or, run the test binary directly
289# (which gives more fine-grained control like filtering):
290<dir-to-glslangtests-in-build-dir>/glslangtests
291```
292
293Running `runtests` script-backed tests:
294
295```bash
296cd $SOURCE_DIR/Test && ./runtests
297```
298
299If some tests fail with validation errors, there may be a mismatch between the
300version of `spirv-val` on the system and the version of glslang.  In this
301case, it is necessary to run `update_glslang_sources.py`.  See "Check-Out
302External Projects" above for more details.
303
304### Contributing tests
305
306Test results should always be included with a pull request that modifies
307functionality.
308
309If you are writing unit tests, please use the Google Test framework and
310place the tests under the `gtests/` directory.
311
312Integration tests are placed in the `Test/` directory. It contains test input
313and a subdirectory `baseResults/` that contains the expected results of the
314tests.  Both the tests and `baseResults/` are under source-code control.
315
316Google Test runs those integration tests by reading the test input, compiling
317them, and then compare against the expected results in `baseResults/`. The
318integration tests to run via Google Test is registered in various
319`gtests/*.FromFile.cpp` source files. `glslangtests` provides a command-line
320option `--update-mode`, which, if supplied, will overwrite the golden files
321under the `baseResults/` directory with real output from that invocation.
322For more information, please check `gtests/` directory's
323[README](gtests/README.md).
324
325For the `runtests` script, it will generate current results in the
326`localResults/` directory and `diff` them against the `baseResults/`.
327When you want to update the tracked test results, they need to be
328copied from `localResults/` to `baseResults/`.  This can be done by
329the `bump` shell script.
330
331You can add your own private list of tests, not tracked publicly, by using
332`localtestlist` to list non-tracked tests.  This is automatically read
333by `runtests` and included in the `diff` and `bump` process.
334
335## Programmatic Interfaces
336
337Another piece of software can programmatically translate shaders to an AST
338using one of two different interfaces:
339* A new C++ class-oriented interface, or
340* The original C functional interface
341
342The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles.
343
344### C++ Class Interface (new, preferred)
345
346This interface is in roughly the last 1/3 of `ShaderLang.h`.  It is in the
347glslang namespace and contains the following, here with suggested calls
348for generating SPIR-V:
349
350```cxx
351const char* GetEsslVersionString();
352const char* GetGlslVersionString();
353bool InitializeProcess();
354void FinalizeProcess();
355
356class TShader
357    setStrings(...);
358    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientVulkan or EShClientOpenGL, 100);
359    setEnvClient(EShClientVulkan or EShClientOpenGL, EShTargetVulkan_1_0 or EShTargetVulkan_1_1 or EShTargetOpenGL_450);
360    setEnvTarget(EShTargetSpv, EShTargetSpv_1_0 or EShTargetSpv_1_3);
361    bool parse(...);
362    const char* getInfoLog();
363
364class TProgram
365    void addShader(...);
366    bool link(...);
367    const char* getInfoLog();
368    Reflection queries
369```
370
371For just validating (not generating code), substitute these calls:
372
373```cxx
374    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientNone, 0);
375    setEnvClient(EShClientNone, 0);
376    setEnvTarget(EShTargetNone, 0);
377```
378
379See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
380details. There is a block comment giving more detail above the calls for
381`setEnvInput, setEnvClient, and setEnvTarget`.
382
383### C Functional Interface (original)
384
385This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
386as the `Sh*()` interface, as all the entry points start `Sh`.
387
388The `Sh*()` interface takes a "compiler" call-back object, which it calls after
389building call back that is passed the AST and can then execute a back end on it.
390
391The following is a simplified resulting run-time call stack:
392
393```c
394ShCompile(shader, compiler) -> compiler(AST) -> <back end>
395```
396
397In practice, `ShCompile()` takes shader strings, default version, and
398warning/error and other options for controlling compilation.
399
400### C Functional Interface (new)
401
402This interface is located `glslang_c_interface.h` and exposes functionality similar to the C++ interface. The following snippet is a complete example showing how to compile GLSL into SPIR-V 1.5 for Vulkan 1.2.
403
404```c
405#include <glslang/Include/glslang_c_interface.h>
406
407// Required for use of glslang_default_resource
408#include <glslang/Public/resource_limits_c.h>
409
410typedef struct SpirVBinary {
411    uint32_t *words; // SPIR-V words
412    int size; // number of words in SPIR-V binary
413} SpirVBinary;
414
415SpirVBinary compileShaderToSPIRV_Vulkan(glslang_stage_t stage, const char* shaderSource, const char* fileName) {
416    const glslang_input_t input = {
417        .language = GLSLANG_SOURCE_GLSL,
418        .stage = stage,
419        .client = GLSLANG_CLIENT_VULKAN,
420        .client_version = GLSLANG_TARGET_VULKAN_1_2,
421        .target_language = GLSLANG_TARGET_SPV,
422        .target_language_version = GLSLANG_TARGET_SPV_1_5,
423        .code = shaderSource,
424        .default_version = 100,
425        .default_profile = GLSLANG_NO_PROFILE,
426        .force_default_version_and_profile = false,
427        .forward_compatible = false,
428        .messages = GLSLANG_MSG_DEFAULT_BIT,
429        .resource = glslang_default_resource(),
430    };
431
432    glslang_shader_t* shader = glslang_shader_create(&input);
433
434    SpirVBinary bin = {
435        .words = NULL,
436        .size = 0,
437    };
438    if (!glslang_shader_preprocess(shader, &input))	{
439        printf("GLSL preprocessing failed %s\n", fileName);
440        printf("%s\n", glslang_shader_get_info_log(shader));
441        printf("%s\n", glslang_shader_get_info_debug_log(shader));
442        printf("%s\n", input.code);
443        glslang_shader_delete(shader);
444        return bin;
445    }
446
447    if (!glslang_shader_parse(shader, &input)) {
448        printf("GLSL parsing failed %s\n", fileName);
449        printf("%s\n", glslang_shader_get_info_log(shader));
450        printf("%s\n", glslang_shader_get_info_debug_log(shader));
451        printf("%s\n", glslang_shader_get_preprocessed_code(shader));
452        glslang_shader_delete(shader);
453        return bin;
454    }
455
456    glslang_program_t* program = glslang_program_create();
457    glslang_program_add_shader(program, shader);
458
459    if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT)) {
460        printf("GLSL linking failed %s\n", fileName);
461        printf("%s\n", glslang_program_get_info_log(program));
462        printf("%s\n", glslang_program_get_info_debug_log(program));
463        glslang_program_delete(program);
464        glslang_shader_delete(shader);
465        return bin;
466    }
467
468    glslang_program_SPIRV_generate(program, stage);
469
470    bin.size = glslang_program_SPIRV_get_size(program);
471    bin.words = malloc(bin.size * sizeof(uint32_t));
472    glslang_program_SPIRV_get(program, bin.words);
473
474    const char* spirv_messages = glslang_program_SPIRV_get_messages(program);
475    if (spirv_messages)
476        printf("(%s) %s\b", fileName, spirv_messages);
477
478    glslang_program_delete(program);
479    glslang_shader_delete(shader);
480
481    return bin;
482}
483```
484
485## Basic Internal Operation
486
487* Initial lexical analysis is done by the preprocessor in
488  `MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
489  in `MachineIndependent/Scan.cpp`.  There is currently no use of flex.
490
491* Code is parsed using bison on `MachineIndependent/glslang.y` with the
492  aid of a symbol table and an AST.  The symbol table is not passed on to
493  the back-end; the intermediate representation stands on its own.
494  The tree is built by the grammar productions, many of which are
495  offloaded into `ParseHelper.cpp`, and by `Intermediate.cpp`.
496
497* The intermediate representation is very high-level, and represented
498  as an in-memory tree.   This serves to lose no information from the
499  original program, and to have efficient transfer of the result from
500  parsing to the back-end.  In the AST, constants are propagated and
501  folded, and a very small amount of dead code is eliminated.
502
503  To aid linking and reflection, the last top-level branch in the AST
504  lists all global symbols.
505
506* The primary algorithm of the back-end compiler is to traverse the
507  tree (high-level intermediate representation), and create an internal
508  object code representation.  There is an example of how to do this
509  in `MachineIndependent/intermOut.cpp`.
510
511* Reduction of the tree to a linear byte-code style low-level intermediate
512  representation is likely a good way to generate fully optimized code.
513
514* There is currently some dead old-style linker-type code still lying around.
515
516* Memory pool: parsing uses types derived from C++ `std` types, using a
517  custom allocator that puts them in a memory pool.  This makes allocation
518  of individual container/contents just few cycles and deallocation free.
519  This pool is popped after the AST is made and processed.
520
521  The use is simple: if you are going to call `new`, there are three cases:
522
523  - the object comes from the pool (its base class has the macro
524    `POOL_ALLOCATOR_NEW_DELETE` in it) and you do not have to call `delete`
525
526  - it is a `TString`, in which case call `NewPoolTString()`, which gets
527    it from the pool, and there is no corresponding `delete`
528
529  - the object does not come from the pool, and you have to do normal
530    C++ memory management of what you `new`
531
532* Features can be protected by version/extension/stage/profile:
533  See the comment in `glslang/MachineIndependent/Versions.cpp`.
534
535[cmake]: https://cmake.org/
536[python]: https://www.python.org/
537[bison]: https://www.gnu.org/software/bison/
538[googletest]: https://github.com/google/googletest
539[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
540[main-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/main-tot
541