1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4  *
5  * Large chunks of this file are derived from the glsl crate which is:
6  * Copyright (c) 2018, Dimitri Sabadie <dimitri.sabadie@gmail.com>
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  *   * Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *
16  *   * Redistributions in binary form must reproduce the above
17  *     copyright notice, this list of conditions and the following
18  *     disclaimer in the documentation and/or other materials provided
19  *     with the distribution.
20  *
21  *   * Neither the name of Dimitri Sabadie <dimitri.sabadie@gmail.com> nor the names of other
22  *     contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 
37 use glsl::syntax;
38 use glsl::syntax::{ArrayedIdentifier, ArraySpecifier, AssignmentOp, BinaryOp, Identifier};
39 use glsl::syntax::{NonEmpty, PrecisionQualifier, StructFieldSpecifier, StructSpecifier};
40 use glsl::syntax::{TypeSpecifier, TypeSpecifierNonArray, UnaryOp};
41 use std::cell::{Cell, Ref, RefCell};
42 use std::collections::HashMap;
43 use std::iter::FromIterator;
44 use std::mem;
45 use std::ops::{Deref, DerefMut};
46 use std::rc::Rc;
47 
48 trait LiftFrom<S> {
lift(state: &mut State, s: S) -> Self49     fn lift(state: &mut State, s: S) -> Self;
50 }
51 
lift<S, T: LiftFrom<S>>(state: &mut State, s: S) -> T52 fn lift<S, T: LiftFrom<S>>(state: &mut State, s: S) -> T {
53     LiftFrom::lift(state, s)
54 }
55 
56 #[derive(Debug)]
57 pub struct Symbol {
58     pub name: String,
59     pub decl: SymDecl,
60 }
61 
62 #[derive(Debug, Clone, PartialEq)]
63 pub struct FunctionSignature {
64     ret: Type,
65     params: Vec<Type>,
66 }
67 
68 #[derive(Debug, Clone, PartialEq)]
69 pub struct FunctionType {
70     signatures: NonEmpty<FunctionSignature>,
71 }
72 
73 #[derive(Clone, Copy, Debug, PartialEq)]
74 pub enum SamplerFormat {
75     Unknown,
76     RGBA8,
77     RGBA32F,
78     RGBA32I,
79     R8,
80     RG8,
81 }
82 
83 impl SamplerFormat {
type_suffix(self) -> Option<&'static str>84     pub fn type_suffix(self) -> Option<&'static str> {
85         match self {
86             SamplerFormat::Unknown => None,
87             SamplerFormat::RGBA8 => Some("RGBA8"),
88             SamplerFormat::RGBA32F => Some("RGBA32F"),
89             SamplerFormat::RGBA32I => Some("RGBA32I"),
90             SamplerFormat::R8 => Some("R8"),
91             SamplerFormat::RG8 => Some("RG8"),
92         }
93     }
94 }
95 
96 #[derive(Clone, Copy, Debug, PartialEq)]
97 pub enum StorageClass {
98     None,
99     Const,
100     In,
101     Out,
102     Uniform,
103     Sampler(SamplerFormat),
104     FragColor(i32),
105 }
106 
107 #[derive(Clone, Debug, PartialEq)]
108 pub struct ArraySizes {
109     pub sizes: Vec<Expr>,
110 }
111 
112 impl LiftFrom<&ArraySpecifier> for ArraySizes {
lift(state: &mut State, a: &ArraySpecifier) -> Self113     fn lift(state: &mut State, a: &ArraySpecifier) -> Self {
114         ArraySizes {
115             sizes: vec![match a {
116                 ArraySpecifier::Unsized => panic!(),
117                 ArraySpecifier::ExplicitlySized(expr) => translate_expression(state, expr),
118             }],
119         }
120     }
121 }
122 
123 #[derive(Copy, Clone, Debug, PartialEq)]
124 pub enum TypeKind {
125     Void,
126     Bool,
127     Int,
128     UInt,
129     Float,
130     Double,
131     Vec2,
132     Vec3,
133     Vec4,
134     DVec2,
135     DVec3,
136     DVec4,
137     BVec2,
138     BVec3,
139     BVec4,
140     IVec2,
141     IVec3,
142     IVec4,
143     UVec2,
144     UVec3,
145     UVec4,
146     Mat2,
147     Mat3,
148     Mat4,
149     Mat23,
150     Mat24,
151     Mat32,
152     Mat34,
153     Mat42,
154     Mat43,
155     DMat2,
156     DMat3,
157     DMat4,
158     DMat23,
159     DMat24,
160     DMat32,
161     DMat34,
162     DMat42,
163     DMat43,
164     // floating point opaque types
165     Sampler1D,
166     Image1D,
167     Sampler2D,
168     Image2D,
169     Sampler3D,
170     Image3D,
171     SamplerCube,
172     ImageCube,
173     Sampler2DRect,
174     Image2DRect,
175     Sampler1DArray,
176     Image1DArray,
177     Sampler2DArray,
178     Image2DArray,
179     SamplerBuffer,
180     ImageBuffer,
181     Sampler2DMS,
182     Image2DMS,
183     Sampler2DMSArray,
184     Image2DMSArray,
185     SamplerCubeArray,
186     ImageCubeArray,
187     Sampler1DShadow,
188     Sampler2DShadow,
189     Sampler2DRectShadow,
190     Sampler1DArrayShadow,
191     Sampler2DArrayShadow,
192     SamplerCubeShadow,
193     SamplerCubeArrayShadow,
194     // signed integer opaque types
195     ISampler1D,
196     IImage1D,
197     ISampler2D,
198     IImage2D,
199     ISampler3D,
200     IImage3D,
201     ISamplerCube,
202     IImageCube,
203     ISampler2DRect,
204     IImage2DRect,
205     ISampler1DArray,
206     IImage1DArray,
207     ISampler2DArray,
208     IImage2DArray,
209     ISamplerBuffer,
210     IImageBuffer,
211     ISampler2DMS,
212     IImage2DMS,
213     ISampler2DMSArray,
214     IImage2DMSArray,
215     ISamplerCubeArray,
216     IImageCubeArray,
217     // unsigned integer opaque types
218     AtomicUInt,
219     USampler1D,
220     UImage1D,
221     USampler2D,
222     UImage2D,
223     USampler3D,
224     UImage3D,
225     USamplerCube,
226     UImageCube,
227     USampler2DRect,
228     UImage2DRect,
229     USampler1DArray,
230     UImage1DArray,
231     USampler2DArray,
232     UImage2DArray,
233     USamplerBuffer,
234     UImageBuffer,
235     USampler2DMS,
236     UImage2DMS,
237     USampler2DMSArray,
238     UImage2DMSArray,
239     USamplerCubeArray,
240     UImageCubeArray,
241     Struct(SymRef),
242 }
243 
244 impl TypeKind {
is_sampler(&self) -> bool245     pub fn is_sampler(&self) -> bool {
246         use TypeKind::*;
247         match self {
248             Sampler1D
249             | Image1D
250             | Sampler2D
251             | Image2D
252             | Sampler3D
253             | Image3D
254             | SamplerCube
255             | ImageCube
256             | Sampler2DRect
257             | Image2DRect
258             | Sampler1DArray
259             | Image1DArray
260             | Sampler2DArray
261             | Image2DArray
262             | SamplerBuffer
263             | ImageBuffer
264             | Sampler2DMS
265             | Image2DMS
266             | Sampler2DMSArray
267             | Image2DMSArray
268             | SamplerCubeArray
269             | ImageCubeArray
270             | Sampler1DShadow
271             | Sampler2DShadow
272             | Sampler2DRectShadow
273             | Sampler1DArrayShadow
274             | Sampler2DArrayShadow
275             | SamplerCubeShadow
276             | SamplerCubeArrayShadow
277             | ISampler1D
278             | IImage1D
279             | ISampler2D
280             | IImage2D
281             | ISampler3D
282             | IImage3D
283             | ISamplerCube
284             | IImageCube
285             | ISampler2DRect
286             | IImage2DRect
287             | ISampler1DArray
288             | IImage1DArray
289             | ISampler2DArray
290             | IImage2DArray
291             | ISamplerBuffer
292             | IImageBuffer
293             | ISampler2DMS
294             | IImage2DMS
295             | ISampler2DMSArray
296             | IImage2DMSArray
297             | ISamplerCubeArray
298             | IImageCubeArray
299             | USampler1D
300             | UImage1D
301             | USampler2D
302             | UImage2D
303             | USampler3D
304             | UImage3D
305             | USamplerCube
306             | UImageCube
307             | USampler2DRect
308             | UImage2DRect
309             | USampler1DArray
310             | UImage1DArray
311             | USampler2DArray
312             | UImage2DArray
313             | USamplerBuffer
314             | UImageBuffer
315             | USampler2DMS
316             | UImage2DMS
317             | USampler2DMSArray
318             | UImage2DMSArray
319             | USamplerCubeArray
320             | UImageCubeArray => true,
321             _ => false,
322         }
323     }
324 
is_bool(&self) -> bool325     pub fn is_bool(&self) -> bool {
326         use TypeKind::*;
327         match self {
328             Bool | BVec2 | BVec3 | BVec4 => true,
329             _ => false,
330         }
331     }
332 
to_bool(&self) -> Self333     pub fn to_bool(&self) -> Self {
334         use TypeKind::*;
335         match self {
336             Int | UInt | Float | Double => Bool,
337             IVec2 | UVec2 | Vec2 | DVec2 => BVec2,
338             IVec3 | UVec3 | Vec3 | DVec3 => BVec3,
339             IVec4 | UVec4 | Vec4 | DVec4 => BVec4,
340             _ => *self,
341         }
342     }
343 
to_int(&self) -> Self344     pub fn to_int(&self) -> Self {
345         use TypeKind::*;
346         match self {
347             Bool | UInt | Float | Double => Int,
348             BVec2 | UVec2 | Vec2 | DVec2 => IVec2,
349             BVec3 | UVec3 | Vec3 | DVec3 => IVec3,
350             BVec4 | UVec4 | Vec4 | DVec4 => IVec4,
351             _ => *self,
352         }
353     }
354 
to_scalar(&self) -> Self355     pub fn to_scalar(&self) -> Self {
356         use TypeKind::*;
357         match self {
358             IVec2 | IVec3 | IVec4 => Int,
359             UVec2 | UVec3 | UVec4 => UInt,
360             Vec2 | Vec3 | Vec4 => Float,
361             DVec2 | DVec3 | DVec4 => Double,
362             BVec2 | BVec3 | BVec4 => Bool,
363             _ => *self,
364         }
365     }
366 
glsl_primitive_type_name(&self) -> Option<&'static str>367     pub fn glsl_primitive_type_name(&self) -> Option<&'static str> {
368         use TypeKind::*;
369         Some(match self {
370             Void => "void",
371             Bool => "bool",
372             Int => "int",
373             UInt => "uint",
374             Float => "float",
375             Double => "double",
376             Vec2 => "vec2",
377             Vec3 => "vec3",
378             Vec4 => "vec4",
379             DVec2 => "dvec2",
380             DVec3 => "dvec3",
381             DVec4 => "dvec4",
382             BVec2 => "bvec2",
383             BVec3 => "bvec3",
384             BVec4 => "bvec4",
385             IVec2 => "ivec2",
386             IVec3 => "ivec3",
387             IVec4 => "ivec4",
388             UVec2 => "uvec2",
389             UVec3 => "uvec3",
390             UVec4 => "uvec4",
391             Mat2 => "mat2",
392             Mat3 => "mat3",
393             Mat4 => "mat4",
394             Mat23 => "mat23",
395             Mat24 => "mat24",
396             Mat32 => "mat32",
397             Mat34 => "mat34",
398             Mat42 => "mat42",
399             Mat43 => "mat43",
400             DMat2 => "dmat2",
401             DMat3 => "dmat3",
402             DMat4 => "dmat4",
403             DMat23 => "dmat23",
404             DMat24 => "dmat24",
405             DMat32 => "dmat32",
406             DMat34 => "dmat34",
407             DMat42 => "dmat42",
408             DMat43 => "dmat43",
409             Sampler1D => "sampler1D",
410             Image1D => "image1D",
411             Sampler2D => "sampler2D",
412             Image2D => "image2D",
413             Sampler3D => "sampler3D",
414             Image3D => "image3D",
415             SamplerCube => "samplerCube",
416             ImageCube => "imageCube",
417             Sampler2DRect => "sampler2DRect",
418             Image2DRect => "image2DRect",
419             Sampler1DArray => "sampler1DArray",
420             Image1DArray => "image1DArray",
421             Sampler2DArray => "sampler2DArray",
422             Image2DArray => "image2DArray",
423             SamplerBuffer => "samplerBuffer",
424             ImageBuffer => "imageBuffer",
425             Sampler2DMS => "sampler2DMS",
426             Image2DMS => "image2DMS",
427             Sampler2DMSArray => "sampler2DMSArray",
428             Image2DMSArray => "image2DMSArray",
429             SamplerCubeArray => "samplerCubeArray",
430             ImageCubeArray => "imageCubeArray",
431             Sampler1DShadow => "sampler1DShadow",
432             Sampler2DShadow => "sampler2DShadow",
433             Sampler2DRectShadow => "sampler2DRectShadow",
434             Sampler1DArrayShadow => "sampler1DArrayShadow",
435             Sampler2DArrayShadow => "sampler2DArrayShadow",
436             SamplerCubeShadow => "samplerCubeShadow",
437             SamplerCubeArrayShadow => "samplerCubeArrayShadow",
438             ISampler1D => "isampler1D",
439             IImage1D => "iimage1D",
440             ISampler2D => "isampler2D",
441             IImage2D => "iimage2D",
442             ISampler3D => "isampler3D",
443             IImage3D => "iimage3D",
444             ISamplerCube => "isamplerCube",
445             IImageCube => "iimageCube",
446             ISampler2DRect => "isampler2DRect",
447             IImage2DRect => "iimage2DRect",
448             ISampler1DArray => "isampler1DArray",
449             IImage1DArray => "iimage1DArray",
450             ISampler2DArray => "isampler2DArray",
451             IImage2DArray => "iimage2DArray",
452             ISamplerBuffer => "isamplerBuffer",
453             IImageBuffer => "iimageBuffer",
454             ISampler2DMS => "isampler2MS",
455             IImage2DMS => "iimage2DMS",
456             ISampler2DMSArray => "isampler2DMSArray",
457             IImage2DMSArray => "iimage2DMSArray",
458             ISamplerCubeArray => "isamplerCubeArray",
459             IImageCubeArray => "iimageCubeArray",
460             AtomicUInt => "atomic_uint",
461             USampler1D => "usampler1D",
462             UImage1D => "uimage1D",
463             USampler2D => "usampler2D",
464             UImage2D => "uimage2D",
465             USampler3D => "usampler3D",
466             UImage3D => "uimage3D",
467             USamplerCube => "usamplerCube",
468             UImageCube => "uimageCube",
469             USampler2DRect => "usampler2DRect",
470             UImage2DRect => "uimage2DRect",
471             USampler1DArray => "usampler1DArray",
472             UImage1DArray => "uimage1DArray",
473             USampler2DArray => "usampler2DArray",
474             UImage2DArray => "uimage2DArray",
475             USamplerBuffer => "usamplerBuffer",
476             UImageBuffer => "uimageBuffer",
477             USampler2DMS => "usampler2DMS",
478             UImage2DMS => "uimage2DMS",
479             USampler2DMSArray => "usamplerDMSArray",
480             UImage2DMSArray => "uimage2DMSArray",
481             USamplerCubeArray => "usamplerCubeArray",
482             UImageCubeArray => "uimageCubeArray",
483             Struct(..) => return None,
484         })
485     }
486 
cxx_primitive_type_name(&self) -> Option<&'static str>487     pub fn cxx_primitive_type_name(&self) -> Option<&'static str> {
488         use TypeKind::*;
489         match self {
490             Bool => Some("Bool"),
491             Int => Some("I32"),
492             UInt => Some("U32"),
493             Float => Some("Float"),
494             Double => Some("Double"),
495             _ => self.glsl_primitive_type_name(),
496         }
497     }
498 
cxx_primitive_scalar_type_name(&self) -> Option<&'static str>499     pub fn cxx_primitive_scalar_type_name(&self) -> Option<&'static str> {
500         use TypeKind::*;
501         match self {
502             Void => Some("void"),
503             Bool => Some("bool"),
504             Int => Some("int32_t"),
505             UInt => Some("uint32_t"),
506             Float => Some("float"),
507             Double => Some("double"),
508             _ => {
509                 if self.is_sampler() {
510                     self.cxx_primitive_type_name()
511                 } else {
512                     None
513                 }
514             }
515         }
516     }
517 
from_glsl_primitive_type_name(name: &str) -> Option<TypeKind>518     pub fn from_glsl_primitive_type_name(name: &str) -> Option<TypeKind> {
519         use TypeKind::*;
520         Some(match name {
521             "void" => Void,
522             "bool" => Bool,
523             "int" => Int,
524             "uint" => UInt,
525             "float" => Float,
526             "double" => Double,
527             "vec2" => Vec2,
528             "vec3" => Vec3,
529             "vec4" => Vec4,
530             "dvec2" => DVec2,
531             "dvec3" => DVec3,
532             "dvec4" => DVec4,
533             "bvec2" => BVec2,
534             "bvec3" => BVec3,
535             "bvec4" => BVec4,
536             "ivec2" => IVec2,
537             "ivec3" => IVec3,
538             "ivec4" => IVec4,
539             "uvec2" => UVec2,
540             "uvec3" => UVec3,
541             "uvec4" => UVec4,
542             "mat2" => Mat2,
543             "mat3" => Mat3,
544             "mat4" => Mat4,
545             "mat23" => Mat23,
546             "mat24" => Mat24,
547             "mat32" => Mat32,
548             "mat34" => Mat34,
549             "mat42" => Mat42,
550             "mat43" => Mat43,
551             "dmat2" => DMat2,
552             "dmat3" => DMat3,
553             "dmat4" => DMat4,
554             "dmat23" => DMat23,
555             "dmat24" => DMat24,
556             "dmat32" => DMat32,
557             "dmat34" => DMat34,
558             "dmat42" => DMat42,
559             "dmat43" => DMat43,
560             "sampler1D" => Sampler1D,
561             "image1D" => Image1D,
562             "sampler2D" => Sampler2D,
563             "image2D" => Image2D,
564             "sampler3D" => Sampler3D,
565             "image3D" => Image3D,
566             "samplerCube" => SamplerCube,
567             "imageCube" => ImageCube,
568             "sampler2DRect" => Sampler2DRect,
569             "image2DRect" => Image2DRect,
570             "sampler1DArray" => Sampler1DArray,
571             "image1DArray" => Image1DArray,
572             "sampler2DArray" => Sampler2DArray,
573             "image2DArray" => Image2DArray,
574             "samplerBuffer" => SamplerBuffer,
575             "imageBuffer" => ImageBuffer,
576             "sampler2DMS" => Sampler2DMS,
577             "image2DMS" => Image2DMS,
578             "sampler2DMSArray" => Sampler2DMSArray,
579             "image2DMSArray" => Image2DMSArray,
580             "samplerCubeArray" => SamplerCubeArray,
581             "imageCubeArray" => ImageCubeArray,
582             "sampler1DShadow" => Sampler1DShadow,
583             "sampler2DShadow" => Sampler2DShadow,
584             "sampler2DRectShadow" => Sampler2DRectShadow,
585             "sampler1DArrayShadow" => Sampler1DArrayShadow,
586             "sampler2DArrayShadow" => Sampler2DArrayShadow,
587             "samplerCubeShadow" => SamplerCubeShadow,
588             "samplerCubeArrayShadow" => SamplerCubeArrayShadow,
589             "isampler1D" => ISampler1D,
590             "iimage1D" => IImage1D,
591             "isampler2D" => ISampler2D,
592             "iimage2D" => IImage2D,
593             "isampler3D" => ISampler3D,
594             "iimage3D" => IImage3D,
595             "isamplerCube" => ISamplerCube,
596             "iimageCube" => IImageCube,
597             "isampler2DRect" => ISampler2DRect,
598             "iimage2DRect" => IImage2DRect,
599             "isampler1DArray" => ISampler1DArray,
600             "iimage1DArray" => IImage1DArray,
601             "isampler2DArray" => ISampler2DArray,
602             "iimage2DArray" => IImage2DArray,
603             "isamplerBuffer" => ISamplerBuffer,
604             "iimageBuffer" => IImageBuffer,
605             "isampler2MS" => ISampler2DMS,
606             "iimage2DMS" => IImage2DMS,
607             "isampler2DMSArray" => ISampler2DMSArray,
608             "iimage2DMSArray" => IImage2DMSArray,
609             "isamplerCubeArray" => ISamplerCubeArray,
610             "iimageCubeArray" => IImageCubeArray,
611             "atomic_uint" => AtomicUInt,
612             "usampler1D" => USampler1D,
613             "uimage1D" => UImage1D,
614             "usampler2D" => USampler2D,
615             "uimage2D" => UImage2D,
616             "usampler3D" => USampler3D,
617             "uimage3D" => UImage3D,
618             "usamplerCube" => USamplerCube,
619             "uimageCube" => UImageCube,
620             "usampler2DRect" => USampler2DRect,
621             "uimage2DRect" => UImage2DRect,
622             "usampler1DArray" => USampler1DArray,
623             "uimage1DArray" => UImage1DArray,
624             "usampler2DArray" => USampler2DArray,
625             "uimage2DArray" => UImage2DArray,
626             "usamplerBuffer" => USamplerBuffer,
627             "uimageBuffer" => UImageBuffer,
628             "usampler2DMS" => USampler2DMS,
629             "uimage2DMS" => UImage2DMS,
630             "usamplerDMSArray" => USampler2DMSArray,
631             "uimage2DMSArray" => UImage2DMSArray,
632             "usamplerCubeArray" => USamplerCubeArray,
633             "uimageCubeArray" => UImageCubeArray,
634             _ => return None,
635         })
636     }
637 
from_primitive_type_specifier(spec: &syntax::TypeSpecifierNonArray) -> Option<TypeKind>638     pub fn from_primitive_type_specifier(spec: &syntax::TypeSpecifierNonArray) -> Option<TypeKind> {
639         use TypeKind::*;
640         Some(match spec {
641             TypeSpecifierNonArray::Void => Void,
642             TypeSpecifierNonArray::Bool => Bool,
643             TypeSpecifierNonArray::Int => Int,
644             TypeSpecifierNonArray::UInt => UInt,
645             TypeSpecifierNonArray::Float => Float,
646             TypeSpecifierNonArray::Double => Double,
647             TypeSpecifierNonArray::Vec2 => Vec2,
648             TypeSpecifierNonArray::Vec3 => Vec3,
649             TypeSpecifierNonArray::Vec4 => Vec4,
650             TypeSpecifierNonArray::DVec2 => DVec2,
651             TypeSpecifierNonArray::DVec3 => DVec3,
652             TypeSpecifierNonArray::DVec4 => DVec4,
653             TypeSpecifierNonArray::BVec2 => BVec2,
654             TypeSpecifierNonArray::BVec3 => BVec3,
655             TypeSpecifierNonArray::BVec4 => BVec4,
656             TypeSpecifierNonArray::IVec2 => IVec2,
657             TypeSpecifierNonArray::IVec3 => IVec3,
658             TypeSpecifierNonArray::IVec4 => IVec4,
659             TypeSpecifierNonArray::UVec2 => UVec2,
660             TypeSpecifierNonArray::UVec3 => UVec3,
661             TypeSpecifierNonArray::UVec4 => UVec4,
662             TypeSpecifierNonArray::Mat2 => Mat2,
663             TypeSpecifierNonArray::Mat3 => Mat3,
664             TypeSpecifierNonArray::Mat4 => Mat4,
665             TypeSpecifierNonArray::Mat23 => Mat23,
666             TypeSpecifierNonArray::Mat24 => Mat24,
667             TypeSpecifierNonArray::Mat32 => Mat32,
668             TypeSpecifierNonArray::Mat34 => Mat34,
669             TypeSpecifierNonArray::Mat42 => Mat42,
670             TypeSpecifierNonArray::Mat43 => Mat43,
671             TypeSpecifierNonArray::DMat2 => DMat2,
672             TypeSpecifierNonArray::DMat3 => DMat3,
673             TypeSpecifierNonArray::DMat4 => DMat4,
674             TypeSpecifierNonArray::DMat23 => DMat23,
675             TypeSpecifierNonArray::DMat24 => DMat24,
676             TypeSpecifierNonArray::DMat32 => DMat32,
677             TypeSpecifierNonArray::DMat34 => DMat34,
678             TypeSpecifierNonArray::DMat42 => DMat42,
679             TypeSpecifierNonArray::DMat43 => DMat43,
680             TypeSpecifierNonArray::Sampler1D => Sampler1D,
681             TypeSpecifierNonArray::Image1D => Image1D,
682             TypeSpecifierNonArray::Sampler2D => Sampler2D,
683             TypeSpecifierNonArray::Image2D => Image2D,
684             TypeSpecifierNonArray::Sampler3D => Sampler3D,
685             TypeSpecifierNonArray::Image3D => Image3D,
686             TypeSpecifierNonArray::SamplerCube => SamplerCube,
687             TypeSpecifierNonArray::ImageCube => ImageCube,
688             TypeSpecifierNonArray::Sampler2DRect => Sampler2DRect,
689             TypeSpecifierNonArray::Image2DRect => Image2DRect,
690             TypeSpecifierNonArray::Sampler1DArray => Sampler1DArray,
691             TypeSpecifierNonArray::Image1DArray => Image1DArray,
692             TypeSpecifierNonArray::Sampler2DArray => Sampler2DArray,
693             TypeSpecifierNonArray::Image2DArray => Image2DArray,
694             TypeSpecifierNonArray::SamplerBuffer => SamplerBuffer,
695             TypeSpecifierNonArray::ImageBuffer => ImageBuffer,
696             TypeSpecifierNonArray::Sampler2DMS => Sampler2DMS,
697             TypeSpecifierNonArray::Image2DMS => Image2DMS,
698             TypeSpecifierNonArray::Sampler2DMSArray => Sampler2DMSArray,
699             TypeSpecifierNonArray::Image2DMSArray => Image2DMSArray,
700             TypeSpecifierNonArray::SamplerCubeArray => SamplerCubeArray,
701             TypeSpecifierNonArray::ImageCubeArray => ImageCubeArray,
702             TypeSpecifierNonArray::Sampler1DShadow => Sampler1DShadow,
703             TypeSpecifierNonArray::Sampler2DShadow => Sampler2DShadow,
704             TypeSpecifierNonArray::Sampler2DRectShadow => Sampler2DRectShadow,
705             TypeSpecifierNonArray::Sampler1DArrayShadow => Sampler1DArrayShadow,
706             TypeSpecifierNonArray::Sampler2DArrayShadow => Sampler2DArrayShadow,
707             TypeSpecifierNonArray::SamplerCubeShadow => SamplerCubeShadow,
708             TypeSpecifierNonArray::SamplerCubeArrayShadow => SamplerCubeArrayShadow,
709             TypeSpecifierNonArray::ISampler1D => ISampler1D,
710             TypeSpecifierNonArray::IImage1D => IImage1D,
711             TypeSpecifierNonArray::ISampler2D => ISampler2D,
712             TypeSpecifierNonArray::IImage2D => IImage2D,
713             TypeSpecifierNonArray::ISampler3D => ISampler3D,
714             TypeSpecifierNonArray::IImage3D => IImage3D,
715             TypeSpecifierNonArray::ISamplerCube => ISamplerCube,
716             TypeSpecifierNonArray::IImageCube => IImageCube,
717             TypeSpecifierNonArray::ISampler2DRect => ISampler2DRect,
718             TypeSpecifierNonArray::IImage2DRect => IImage2DRect,
719             TypeSpecifierNonArray::ISampler1DArray => ISampler1DArray,
720             TypeSpecifierNonArray::IImage1DArray => IImage1DArray,
721             TypeSpecifierNonArray::ISampler2DArray => ISampler2DArray,
722             TypeSpecifierNonArray::IImage2DArray => IImage2DArray,
723             TypeSpecifierNonArray::ISamplerBuffer => ISamplerBuffer,
724             TypeSpecifierNonArray::IImageBuffer => IImageBuffer,
725             TypeSpecifierNonArray::ISampler2DMS => ISampler2DMS,
726             TypeSpecifierNonArray::IImage2DMS => IImage2DMS,
727             TypeSpecifierNonArray::ISampler2DMSArray => ISampler2DMSArray,
728             TypeSpecifierNonArray::IImage2DMSArray => IImage2DMSArray,
729             TypeSpecifierNonArray::ISamplerCubeArray => ISamplerCubeArray,
730             TypeSpecifierNonArray::IImageCubeArray => IImageCubeArray,
731             TypeSpecifierNonArray::AtomicUInt => AtomicUInt,
732             TypeSpecifierNonArray::USampler1D => USampler1D,
733             TypeSpecifierNonArray::UImage1D => UImage1D,
734             TypeSpecifierNonArray::USampler2D => USampler2D,
735             TypeSpecifierNonArray::UImage2D => UImage2D,
736             TypeSpecifierNonArray::USampler3D => USampler3D,
737             TypeSpecifierNonArray::UImage3D => UImage3D,
738             TypeSpecifierNonArray::USamplerCube => USamplerCube,
739             TypeSpecifierNonArray::UImageCube => UImageCube,
740             TypeSpecifierNonArray::USampler2DRect => USampler2DRect,
741             TypeSpecifierNonArray::UImage2DRect => UImage2DRect,
742             TypeSpecifierNonArray::USampler1DArray => USampler1DArray,
743             TypeSpecifierNonArray::UImage1DArray => UImage1DArray,
744             TypeSpecifierNonArray::USampler2DArray => USampler2DArray,
745             TypeSpecifierNonArray::UImage2DArray => UImage2DArray,
746             TypeSpecifierNonArray::USamplerBuffer => USamplerBuffer,
747             TypeSpecifierNonArray::UImageBuffer => UImageBuffer,
748             TypeSpecifierNonArray::USampler2DMS => USampler2DMS,
749             TypeSpecifierNonArray::UImage2DMS => UImage2DMS,
750             TypeSpecifierNonArray::USampler2DMSArray => USampler2DMSArray,
751             TypeSpecifierNonArray::UImage2DMSArray => UImage2DMSArray,
752             TypeSpecifierNonArray::USamplerCubeArray => USamplerCubeArray,
753             TypeSpecifierNonArray::UImageCubeArray => UImageCubeArray,
754             TypeSpecifierNonArray::Struct(..) | TypeSpecifierNonArray::TypeName(..) => return None,
755         })
756     }
757 }
758 
759 impl LiftFrom<&syntax::TypeSpecifierNonArray> for TypeKind {
lift(state: &mut State, spec: &syntax::TypeSpecifierNonArray) -> Self760     fn lift(state: &mut State, spec: &syntax::TypeSpecifierNonArray) -> Self {
761         use TypeKind::*;
762         if let Some(kind) = TypeKind::from_primitive_type_specifier(spec) {
763             kind
764         } else {
765             match spec {
766                 TypeSpecifierNonArray::Struct(s) => {
767                     Struct(state.lookup(s.name.as_ref().unwrap().as_str()).unwrap())
768                 }
769                 TypeSpecifierNonArray::TypeName(s) => Struct(state.lookup(&s.0).unwrap()),
770                 _ => unreachable!(),
771             }
772         }
773     }
774 }
775 
776 #[derive(Clone, Debug, PartialEq)]
777 pub struct Type {
778     pub kind: TypeKind,
779     pub precision: Option<PrecisionQualifier>,
780     pub array_sizes: Option<Box<ArraySizes>>,
781 }
782 
783 impl Type {
new(kind: TypeKind) -> Self784     pub fn new(kind: TypeKind) -> Self {
785         Type {
786             kind,
787             precision: None,
788             array_sizes: None,
789         }
790     }
791 
new_array(kind: TypeKind, size: i32) -> Self792     pub fn new_array(kind: TypeKind, size: i32) -> Self {
793         Type {
794             kind,
795             precision: None,
796             array_sizes: Some(Box::new(ArraySizes { sizes: vec![make_const(TypeKind::Int, size)] })),
797         }
798     }
799 }
800 
801 impl LiftFrom<&syntax::FullySpecifiedType> for Type {
lift(state: &mut State, ty: &syntax::FullySpecifiedType) -> Self802     fn lift(state: &mut State, ty: &syntax::FullySpecifiedType) -> Self {
803         let kind = lift(state, &ty.ty.ty);
804         let array_sizes = match ty.ty.array_specifier.as_ref() {
805             Some(x) => Some(Box::new(lift(state, x))),
806             None => None,
807         };
808         let precision = get_precision(&ty.qualifier);
809         Type {
810             kind,
811             precision,
812             array_sizes,
813         }
814     }
815 }
816 
817 impl LiftFrom<&syntax::TypeSpecifier> for Type {
lift(state: &mut State, ty: &syntax::TypeSpecifier) -> Self818     fn lift(state: &mut State, ty: &syntax::TypeSpecifier) -> Self {
819         let kind = lift(state, &ty.ty);
820         let array_sizes = ty
821             .array_specifier
822             .as_ref()
823             .map(|x| Box::new(lift(state, x)));
824         Type {
825             kind,
826             precision: None,
827             array_sizes,
828         }
829     }
830 }
831 
832 #[derive(Debug, Clone, PartialEq)]
833 pub struct StructField {
834     pub ty: Type,
835     pub name: syntax::Identifier,
836 }
837 
get_precision(qualifiers: &Option<syntax::TypeQualifier>) -> Option<PrecisionQualifier>838 fn get_precision(qualifiers: &Option<syntax::TypeQualifier>) -> Option<PrecisionQualifier> {
839     let mut precision = None;
840     for qual in qualifiers.iter().flat_map(|x| x.qualifiers.0.iter()) {
841         match qual {
842             syntax::TypeQualifierSpec::Precision(p) => {
843                 if precision.is_some() {
844                     panic!("Multiple precisions");
845                 }
846                 precision = Some(p.clone());
847             }
848             _ => {}
849         }
850     }
851     precision
852 }
853 
854 impl LiftFrom<&StructFieldSpecifier> for StructField {
lift(state: &mut State, f: &StructFieldSpecifier) -> Self855     fn lift(state: &mut State, f: &StructFieldSpecifier) -> Self {
856         let mut ty: Type = lift(state, &f.ty);
857         match &f.identifiers.0[..] {
858             [ident] => {
859                 if let Some(a) = &ident.array_spec {
860                     ty.array_sizes = Some(Box::new(lift(state, a)));
861                 }
862                 StructField {
863                     ty,
864                     name: ident.ident.clone(),
865                 }
866             }
867             _ => panic!("bad number of identifiers"),
868         }
869     }
870 }
871 
872 #[derive(Debug, Clone, PartialEq)]
873 pub struct StructFields {
874     pub fields: Vec<StructField>,
875 }
876 
877 impl LiftFrom<&StructSpecifier> for StructFields {
lift(state: &mut State, s: &StructSpecifier) -> Self878     fn lift(state: &mut State, s: &StructSpecifier) -> Self {
879         let fields = s.fields.0.iter().map(|field| lift(state, field)).collect();
880         Self { fields }
881     }
882 }
883 
884 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
885 pub enum RunClass {
886     Unknown,
887     Scalar,
888     Vector,
889     Dependent(u32),
890 }
891 
892 impl RunClass {
merge(self, run_class: RunClass) -> RunClass893     pub fn merge(self, run_class: RunClass) -> RunClass {
894         match (self, run_class) {
895             (RunClass::Vector, _) | (_, RunClass::Vector) => RunClass::Vector,
896             (RunClass::Dependent(x), RunClass::Dependent(y)) => RunClass::Dependent(x | y),
897             (RunClass::Unknown, _) | (_, RunClass::Dependent(..)) => run_class,
898             _ => self,
899         }
900     }
901 }
902 
903 #[derive(Debug, Clone, PartialEq)]
904 pub enum SymDecl {
905     NativeFunction(FunctionType, Option<&'static str>, RunClass),
906     UserFunction(Rc<FunctionDefinition>, RunClass),
907     Local(StorageClass, Type, RunClass),
908     Global(
909         StorageClass,
910         Option<syntax::InterpolationQualifier>,
911         Type,
912         RunClass,
913     ),
914     Struct(StructFields),
915 }
916 
917 #[derive(Clone, Debug, PartialEq, Copy, Eq, Hash)]
918 pub struct SymRef(u32);
919 
920 #[derive(Debug)]
921 struct Scope {
922     // The field is not actively used but useful for `Debug`.
923     #[allow(dead_code)]
924     name: String,
925     names: HashMap<String, SymRef>,
926 }
927 impl Scope {
new(name: String) -> Self928     fn new(name: String) -> Self {
929         Scope {
930             name,
931             names: HashMap::new(),
932         }
933     }
934 }
935 
936 #[derive(Clone, Debug, PartialEq)]
937 pub struct TexelFetchOffsets {
938     pub min_x: i32,
939     pub max_x: i32,
940     pub min_y: i32,
941     pub max_y: i32,
942 }
943 
944 impl TexelFetchOffsets {
new(x: i32, y: i32) -> Self945     fn new(x: i32, y: i32) -> Self {
946         TexelFetchOffsets {
947             min_x: x,
948             max_x: x,
949             min_y: y,
950             max_y: y,
951         }
952     }
953 
add_offset(&mut self, x: i32, y: i32)954     fn add_offset(&mut self, x: i32, y: i32) {
955         self.min_x = self.min_x.min(x);
956         self.max_x = self.max_x.max(x);
957         self.min_y = self.min_y.min(y);
958         self.max_y = self.max_y.max(y);
959     }
960 }
961 
962 #[derive(Debug)]
963 pub struct State {
964     scopes: Vec<Scope>,
965     syms: Vec<RefCell<Symbol>>,
966     in_function: Option<SymRef>,
967     run_class_changed: Cell<bool>,
968     last_declaration: SymRef,
969     branch_run_class: RunClass,
970     branch_declaration: SymRef,
971     modified_globals: RefCell<Vec<SymRef>>,
972     pub used_globals: RefCell<Vec<SymRef>>,
973     pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
974     clip_dist_sym: SymRef,
975     pub used_clip_dist: u32,
976 }
977 
978 impl State {
new() -> Self979     pub fn new() -> Self {
980         State {
981             scopes: Vec::new(),
982             syms: Vec::new(),
983             in_function: None,
984             run_class_changed: Cell::new(false),
985             last_declaration: SymRef(0),
986             branch_run_class: RunClass::Unknown,
987             branch_declaration: SymRef(0),
988             modified_globals: RefCell::new(Vec::new()),
989             used_globals: RefCell::new(Vec::new()),
990             texel_fetches: HashMap::new(),
991             clip_dist_sym: SymRef(0),
992             used_clip_dist: 0,
993         }
994     }
995 
lookup(&self, name: &str) -> Option<SymRef>996     pub fn lookup(&self, name: &str) -> Option<SymRef> {
997         for s in self.scopes.iter().rev() {
998             if let Some(sym) = s.names.get(name) {
999                 return Some(*sym);
1000             }
1001         }
1002         return None;
1003     }
1004 
declare(&mut self, name: &str, decl: SymDecl) -> SymRef1005     fn declare(&mut self, name: &str, decl: SymDecl) -> SymRef {
1006         let s = SymRef(self.syms.len() as u32);
1007         self.syms.push(RefCell::new(Symbol {
1008             name: name.into(),
1009             decl,
1010         }));
1011         self.scopes.last_mut().unwrap().names.insert(name.into(), s);
1012         s
1013     }
1014 
sym(&self, sym: SymRef) -> Ref<Symbol>1015     pub fn sym(&self, sym: SymRef) -> Ref<Symbol> {
1016         self.syms[sym.0 as usize].borrow()
1017     }
1018 
sym_mut(&mut self, sym: SymRef) -> &mut Symbol1019     pub fn sym_mut(&mut self, sym: SymRef) -> &mut Symbol {
1020         self.syms[sym.0 as usize].get_mut()
1021     }
1022 
lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol>1023     pub fn lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol> {
1024         self.lookup(name)
1025             .map(move |x| self.syms[x.0 as usize].get_mut())
1026     }
1027 
push_scope(&mut self, name: String)1028     fn push_scope(&mut self, name: String) {
1029         self.scopes.push(Scope::new(name));
1030     }
pop_scope(&mut self)1031     fn pop_scope(&mut self) {
1032         self.scopes.pop();
1033     }
1034 
return_run_class(&self, mut new_run_class: RunClass)1035     fn return_run_class(&self, mut new_run_class: RunClass) {
1036         new_run_class = self.branch_run_class.merge(new_run_class);
1037         if let Some(sym) = self.in_function {
1038             let mut b = self.syms[sym.0 as usize].borrow_mut();
1039             if let SymDecl::UserFunction(_, ref mut run_class) = b.decl {
1040                 *run_class = run_class.merge(new_run_class);
1041             }
1042         }
1043     }
1044 
function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)>1045     pub fn function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)> {
1046         if let SymDecl::UserFunction(ref fd, ref run_class) = &self.sym(name).decl {
1047             Some((fd.clone(), *run_class))
1048         } else {
1049             None
1050         }
1051     }
1052 
merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass1053     fn merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass {
1054         if sym.0 <= self.branch_declaration.0 {
1055             new_run_class = self.branch_run_class.merge(new_run_class);
1056         }
1057         let mut b = self.syms[sym.0 as usize].borrow_mut();
1058         let mut old_run_class = new_run_class;
1059         if let SymDecl::Local(_, _, ref mut run_class) = b.decl {
1060             old_run_class = *run_class;
1061             new_run_class = old_run_class.merge(new_run_class);
1062             *run_class = new_run_class;
1063         }
1064         if old_run_class != RunClass::Unknown && old_run_class != new_run_class {
1065             self.run_class_changed.set(true);
1066         }
1067         new_run_class
1068     }
1069 }
1070 
1071 /// A declaration.
1072 #[derive(Clone, Debug, PartialEq)]
1073 pub enum Declaration {
1074     FunctionPrototype(FunctionPrototype),
1075     StructDefinition(SymRef),
1076     InitDeclaratorList(InitDeclaratorList),
1077     Precision(PrecisionQualifier, TypeSpecifier),
1078     Block(Block),
1079     Global(TypeQualifier, Vec<Identifier>),
1080 }
1081 
1082 /// A general purpose block, containing fields and possibly a list of declared identifiers. Semantic
1083 /// is given with the storage qualifier.
1084 #[derive(Clone, Debug, PartialEq)]
1085 pub struct Block {
1086     pub qualifier: TypeQualifier,
1087     pub name: Identifier,
1088     pub fields: Vec<StructFieldSpecifier>,
1089     pub identifier: Option<ArrayedIdentifier>,
1090 }
1091 
1092 /// Function identifier.
1093 #[derive(Clone, Debug, PartialEq)]
1094 pub enum FunIdentifier {
1095     Identifier(SymRef),
1096     Constructor(Type),
1097 }
1098 
1099 /// Function prototype.
1100 #[derive(Clone, Debug, PartialEq)]
1101 pub struct FunctionPrototype {
1102     pub ty: Type,
1103     pub name: Identifier,
1104     pub parameters: Vec<FunctionParameterDeclaration>,
1105 }
1106 
1107 impl FunctionPrototype {
has_parameter(&self, sym: SymRef) -> bool1108     pub fn has_parameter(&self, sym: SymRef) -> bool {
1109         for param in &self.parameters {
1110             match param {
1111                 FunctionParameterDeclaration::Named(_, ref d) => {
1112                     if d.sym == sym {
1113                         return true;
1114                     }
1115                 }
1116                 _ => {}
1117             }
1118         }
1119         false
1120     }
1121 }
1122 
1123 /// Function parameter declaration.
1124 #[derive(Clone, Debug, PartialEq)]
1125 pub enum FunctionParameterDeclaration {
1126     Named(Option<ParameterQualifier>, FunctionParameterDeclarator),
1127     Unnamed(Option<ParameterQualifier>, TypeSpecifier),
1128 }
1129 
1130 /// Function parameter declarator.
1131 #[derive(Clone, Debug, PartialEq)]
1132 pub struct FunctionParameterDeclarator {
1133     pub ty: Type,
1134     pub name: Identifier,
1135     pub sym: SymRef,
1136 }
1137 
1138 /// Init declarator list.
1139 #[derive(Clone, Debug, PartialEq)]
1140 pub struct InitDeclaratorList {
1141     // XXX it feels like separating out the type and the names is better than
1142     // head and tail
1143     // Also, it might be nice to separate out type definitions from name definitions
1144     pub head: SingleDeclaration,
1145     pub tail: Vec<SingleDeclarationNoType>,
1146 }
1147 
1148 /// Type qualifier.
1149 #[derive(Clone, Debug, PartialEq)]
1150 pub struct TypeQualifier {
1151     pub qualifiers: NonEmpty<TypeQualifierSpec>,
1152 }
1153 
lift_type_qualifier_for_declaration( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<TypeQualifier>1154 fn lift_type_qualifier_for_declaration(
1155     _state: &mut State,
1156     q: &Option<syntax::TypeQualifier>,
1157 ) -> Option<TypeQualifier> {
1158     q.as_ref().and_then(|x| {
1159         NonEmpty::from_non_empty_iter(x.qualifiers.0.iter().flat_map(|x| match x {
1160             syntax::TypeQualifierSpec::Precision(_) => None,
1161             syntax::TypeQualifierSpec::Interpolation(_) => None,
1162             syntax::TypeQualifierSpec::Invariant => Some(TypeQualifierSpec::Invariant),
1163             syntax::TypeQualifierSpec::Layout(l) => Some(TypeQualifierSpec::Layout(l.clone())),
1164             syntax::TypeQualifierSpec::Precise => Some(TypeQualifierSpec::Precise),
1165             syntax::TypeQualifierSpec::Storage(_) => None,
1166         }))
1167         .map(|x| TypeQualifier { qualifiers: x })
1168     })
1169 }
1170 
lift_type_qualifier_for_parameter( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<ParameterQualifier>1171 fn lift_type_qualifier_for_parameter(
1172     _state: &mut State,
1173     q: &Option<syntax::TypeQualifier>,
1174 ) -> Option<ParameterQualifier> {
1175     let mut qp: Option<ParameterQualifier> = None;
1176     if let Some(q) = q {
1177         for x in &q.qualifiers.0 {
1178             match (&qp, x) {
1179                 (None, syntax::TypeQualifierSpec::Storage(s)) => match s {
1180                     syntax::StorageQualifier::Const => qp = Some(ParameterQualifier::Const),
1181                     syntax::StorageQualifier::In => qp = Some(ParameterQualifier::In),
1182                     syntax::StorageQualifier::Out => qp = Some(ParameterQualifier::Out),
1183                     syntax::StorageQualifier::InOut => qp = Some(ParameterQualifier::InOut),
1184                     _ => panic!("Bad storage qualifier for parameter"),
1185                 },
1186                 (_, syntax::TypeQualifierSpec::Precision(_)) => {}
1187                 _ => panic!("Bad parameter qualifier {:?}", x),
1188             }
1189         }
1190     }
1191     qp
1192 }
1193 
1194 #[derive(Clone, Debug, PartialEq)]
1195 pub enum ParameterQualifier {
1196     Const,
1197     In,
1198     InOut,
1199     Out,
1200 }
1201 
1202 #[derive(Clone, Debug, PartialEq)]
1203 pub enum MemoryQualifier {
1204     Coherent,
1205     Volatile,
1206     Restrict,
1207     ReadOnly,
1208     WriteOnly,
1209 }
1210 
1211 /// Type qualifier spec.
1212 #[derive(Clone, Debug, PartialEq)]
1213 pub enum TypeQualifierSpec {
1214     Layout(syntax::LayoutQualifier),
1215     Invariant,
1216     Parameter(ParameterQualifier),
1217     Memory(MemoryQualifier),
1218     Precise,
1219 }
1220 
1221 /// Single declaration.
1222 #[derive(Clone, Debug, PartialEq)]
1223 pub struct SingleDeclaration {
1224     pub ty: Type,
1225     pub ty_def: Option<SymRef>,
1226     pub qualifier: Option<TypeQualifier>,
1227     pub name: SymRef,
1228     pub initializer: Option<Initializer>,
1229 }
1230 
1231 /// A single declaration with implicit, already-defined type.
1232 #[derive(Clone, Debug, PartialEq)]
1233 pub struct SingleDeclarationNoType {
1234     pub ident: ArrayedIdentifier,
1235     pub initializer: Option<Initializer>,
1236 }
1237 
1238 /// Initializer.
1239 #[derive(Clone, Debug, PartialEq)]
1240 pub enum Initializer {
1241     Simple(Box<Expr>),
1242     List(NonEmpty<Initializer>),
1243 }
1244 
1245 impl From<Expr> for Initializer {
from(e: Expr) -> Self1246     fn from(e: Expr) -> Self {
1247         Initializer::Simple(Box::new(e))
1248     }
1249 }
1250 
1251 #[derive(Clone, Debug, PartialEq)]
1252 pub struct Expr {
1253     pub kind: ExprKind,
1254     pub ty: Type,
1255 }
1256 
1257 #[derive(Copy, Clone, Debug, PartialEq)]
1258 pub enum FieldSet {
1259     Rgba,
1260     Xyzw,
1261     Stpq,
1262 }
1263 
1264 #[derive(Clone, Debug, PartialEq)]
1265 pub struct SwizzleSelector {
1266     pub field_set: FieldSet,
1267     pub components: Vec<i8>,
1268 }
1269 
1270 impl SwizzleSelector {
parse(s: &str) -> Self1271     fn parse(s: &str) -> Self {
1272         let mut components = Vec::new();
1273         let mut field_set = Vec::new();
1274 
1275         for c in s.chars() {
1276             match c {
1277                 'r' => {
1278                     components.push(0);
1279                     field_set.push(FieldSet::Rgba);
1280                 }
1281                 'x' => {
1282                     components.push(0);
1283                     field_set.push(FieldSet::Xyzw);
1284                 }
1285                 's' => {
1286                     components.push(0);
1287                     field_set.push(FieldSet::Stpq);
1288                 }
1289 
1290                 'g' => {
1291                     components.push(1);
1292                     field_set.push(FieldSet::Rgba);
1293                 }
1294                 'y' => {
1295                     components.push(1);
1296                     field_set.push(FieldSet::Xyzw);
1297                 }
1298                 't' => {
1299                     components.push(1);
1300                     field_set.push(FieldSet::Stpq);
1301                 }
1302 
1303                 'b' => {
1304                     components.push(2);
1305                     field_set.push(FieldSet::Rgba);
1306                 }
1307                 'z' => {
1308                     components.push(2);
1309                     field_set.push(FieldSet::Xyzw);
1310                 }
1311                 'p' => {
1312                     components.push(2);
1313                     field_set.push(FieldSet::Stpq);
1314                 }
1315 
1316                 'a' => {
1317                     components.push(3);
1318                     field_set.push(FieldSet::Rgba);
1319                 }
1320                 'w' => {
1321                     components.push(3);
1322                     field_set.push(FieldSet::Xyzw);
1323                 }
1324                 'q' => {
1325                     components.push(3);
1326                     field_set.push(FieldSet::Stpq);
1327                 }
1328                 _ => panic!("bad selector"),
1329             }
1330         }
1331 
1332         let first = &field_set[0];
1333         assert!(field_set.iter().all(|item| item == first));
1334         assert!(components.len() <= 4);
1335         SwizzleSelector {
1336             field_set: first.clone(),
1337             components,
1338         }
1339     }
1340 
to_field_set(&self, field_set: FieldSet) -> String1341     pub fn to_field_set(&self, field_set: FieldSet) -> String {
1342         let mut s = String::new();
1343         let fs = match field_set {
1344             FieldSet::Rgba => ['r', 'g', 'b', 'a'],
1345             FieldSet::Xyzw => ['x', 'y', 'z', 'w'],
1346             FieldSet::Stpq => ['s', 't', 'p', 'q'],
1347         };
1348         for i in &self.components {
1349             s.push(fs[*i as usize])
1350         }
1351         s
1352     }
1353 
to_string(&self) -> String1354     pub fn to_string(&self) -> String {
1355         self.to_field_set(self.field_set)
1356     }
1357 }
1358 
1359 /// The most general form of an expression. As you can see if you read the variant list, in GLSL, an
1360 /// assignment is an expression. This is a bit silly but think of an assignment as a statement first
1361 /// then an expression which evaluates to what the statement “returns”.
1362 ///
1363 /// An expression is either an assignment or a list (comma) of assignments.
1364 #[derive(Clone, Debug, PartialEq)]
1365 pub enum ExprKind {
1366     /// A variable expression, using an identifier.
1367     Variable(SymRef),
1368     /// Integral constant expression.
1369     IntConst(i32),
1370     /// Unsigned integral constant expression.
1371     UIntConst(u32),
1372     /// Boolean constant expression.
1373     BoolConst(bool),
1374     /// Single precision floating expression.
1375     FloatConst(f32),
1376     /// Double precision floating expression.
1377     DoubleConst(f64),
1378     /// A unary expression, gathering a single expression and a unary operator.
1379     Unary(UnaryOp, Box<Expr>),
1380     /// A binary expression, gathering two expressions and a binary operator.
1381     Binary(BinaryOp, Box<Expr>, Box<Expr>),
1382     /// A ternary conditional expression, gathering three expressions.
1383     Ternary(Box<Expr>, Box<Expr>, Box<Expr>),
1384     /// An assignment is also an expression. Gathers an expression that defines what to assign to, an
1385     /// assignment operator and the value to associate with.
1386     Assignment(Box<Expr>, AssignmentOp, Box<Expr>),
1387     /// Add an array specifier to an expression.
1388     Bracket(Box<Expr>, Box<Expr>),
1389     /// A functional call. It has a function identifier and a list of expressions (arguments).
1390     FunCall(FunIdentifier, Vec<Expr>),
1391     /// An expression associated with a field selection (struct).
1392     Dot(Box<Expr>, Identifier),
1393     /// An expression associated with a component selection
1394     SwizzleSelector(Box<Expr>, SwizzleSelector),
1395     /// Post-incrementation of an expression.
1396     PostInc(Box<Expr>),
1397     /// Post-decrementation of an expression.
1398     PostDec(Box<Expr>),
1399     /// An expression that contains several, separated with comma.
1400     Comma(Box<Expr>, Box<Expr>),
1401     /// A temporary condition variable
1402     Cond(usize, Box<Expr>),
1403     CondMask,
1404 }
1405 
1406 /*
1407 impl From<i32> for Expr {
1408     fn from(x: i32) -> Expr {
1409         ExprKind::IntConst(x)
1410     }
1411 }
1412 
1413 impl From<u32> for Expr {
1414     fn from(x: u32) -> Expr {
1415         Expr::UIntConst(x)
1416     }
1417 }
1418 
1419 impl From<bool> for Expr {
1420     fn from(x: bool) -> Expr {
1421         Expr::BoolConst(x)
1422     }
1423 }
1424 
1425 impl From<f32> for Expr {
1426     fn from(x: f32) -> Expr {
1427         Expr::FloatConst(x)
1428     }
1429 }
1430 
1431 impl From<f64> for Expr {
1432     fn from(x: f64) -> Expr {
1433         Expr::DoubleConst(x)
1434     }
1435 }
1436 */
1437 /// Starting rule.
1438 #[derive(Clone, Debug, PartialEq)]
1439 pub struct TranslationUnit(pub NonEmpty<ExternalDeclaration>);
1440 
1441 impl TranslationUnit {
1442     /// Construct a translation unit from an iterator.
1443     ///
1444     /// # Errors
1445     ///
1446     /// `None` if the iterator yields no value.
from_iter<I>(iter: I) -> Option<Self> where I: IntoIterator<Item = ExternalDeclaration>,1447     pub fn from_iter<I>(iter: I) -> Option<Self>
1448     where
1449         I: IntoIterator<Item = ExternalDeclaration>,
1450     {
1451         NonEmpty::from_non_empty_iter(iter).map(TranslationUnit)
1452     }
1453 }
1454 
1455 impl Deref for TranslationUnit {
1456     type Target = NonEmpty<ExternalDeclaration>;
1457 
deref(&self) -> &Self::Target1458     fn deref(&self) -> &Self::Target {
1459         &self.0
1460     }
1461 }
1462 
1463 impl DerefMut for TranslationUnit {
deref_mut(&mut self) -> &mut Self::Target1464     fn deref_mut(&mut self) -> &mut Self::Target {
1465         &mut self.0
1466     }
1467 }
1468 
1469 impl IntoIterator for TranslationUnit {
1470     type IntoIter = <NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1471     type Item = ExternalDeclaration;
1472 
into_iter(self) -> Self::IntoIter1473     fn into_iter(self) -> Self::IntoIter {
1474         self.0.into_iter()
1475     }
1476 }
1477 
1478 impl<'a> IntoIterator for &'a TranslationUnit {
1479     type IntoIter = <&'a NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1480     type Item = &'a ExternalDeclaration;
1481 
into_iter(self) -> Self::IntoIter1482     fn into_iter(self) -> Self::IntoIter {
1483         (&self.0).into_iter()
1484     }
1485 }
1486 
1487 impl<'a> IntoIterator for &'a mut TranslationUnit {
1488     type IntoIter = <&'a mut NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1489     type Item = &'a mut ExternalDeclaration;
1490 
into_iter(self) -> Self::IntoIter1491     fn into_iter(self) -> Self::IntoIter {
1492         (&mut self.0).into_iter()
1493     }
1494 }
1495 
1496 /// External declaration.
1497 #[derive(Clone, Debug, PartialEq)]
1498 pub enum ExternalDeclaration {
1499     Preprocessor(syntax::Preprocessor),
1500     FunctionDefinition(Rc<FunctionDefinition>),
1501     Declaration(Declaration),
1502 }
1503 
1504 /// Function definition.
1505 #[derive(Clone, Debug, PartialEq)]
1506 pub struct FunctionDefinition {
1507     pub prototype: FunctionPrototype,
1508     pub body: CompoundStatement,
1509     pub globals: Vec<SymRef>,
1510     pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
1511 }
1512 
1513 /// Compound statement (with no new scope).
1514 #[derive(Clone, Debug, PartialEq)]
1515 pub struct CompoundStatement {
1516     pub statement_list: Vec<Statement>,
1517 }
1518 
1519 impl CompoundStatement {
new() -> Self1520     pub fn new() -> Self {
1521         CompoundStatement {
1522             statement_list: Vec::new(),
1523         }
1524     }
1525 }
1526 
1527 impl FromIterator<Statement> for CompoundStatement {
from_iter<T>(iter: T) -> Self where T: IntoIterator<Item = Statement>,1528     fn from_iter<T>(iter: T) -> Self
1529     where
1530         T: IntoIterator<Item = Statement>,
1531     {
1532         CompoundStatement {
1533             statement_list: iter.into_iter().collect(),
1534         }
1535     }
1536 }
1537 
1538 /// Statement.
1539 #[derive(Clone, Debug, PartialEq)]
1540 pub enum Statement {
1541     Compound(Box<CompoundStatement>),
1542     Simple(Box<SimpleStatement>),
1543 }
1544 
1545 /// Simple statement.
1546 #[derive(Clone, Debug, PartialEq)]
1547 pub enum SimpleStatement {
1548     Declaration(Declaration),
1549     Expression(ExprStatement),
1550     Selection(SelectionStatement),
1551     Switch(SwitchStatement),
1552     Iteration(IterationStatement),
1553     Jump(JumpStatement),
1554 }
1555 
1556 impl SimpleStatement {
1557     /// Create a new expression statement.
new_expr<E>(expr: E) -> Self where E: Into<Expr>,1558     pub fn new_expr<E>(expr: E) -> Self
1559     where
1560         E: Into<Expr>,
1561     {
1562         SimpleStatement::Expression(Some(expr.into()))
1563     }
1564 
1565     /// Create a new selection statement (if / else).
new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self where If: Into<Expr>, True: Into<Statement>, False: Into<Statement>,1566     pub fn new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self
1567     where
1568         If: Into<Expr>,
1569         True: Into<Statement>,
1570         False: Into<Statement>,
1571     {
1572         SimpleStatement::Selection(SelectionStatement {
1573             cond: Box::new(ife.into()),
1574             body: Box::new(truee.into()),
1575             else_stmt: Some(Box::new(falsee.into())),
1576         })
1577     }
1578 
1579     /// Create a new while statement.
new_while<C, S>(cond: C, body: S) -> Self where C: Into<Condition>, S: Into<Statement>,1580     pub fn new_while<C, S>(cond: C, body: S) -> Self
1581     where
1582         C: Into<Condition>,
1583         S: Into<Statement>,
1584     {
1585         SimpleStatement::Iteration(IterationStatement::While(
1586             cond.into(),
1587             Box::new(body.into()),
1588         ))
1589     }
1590 
1591     /// Create a new do-while statement.
new_do_while<C, S>(body: S, cond: C) -> Self where S: Into<Statement>, C: Into<Expr>,1592     pub fn new_do_while<C, S>(body: S, cond: C) -> Self
1593     where
1594         S: Into<Statement>,
1595         C: Into<Expr>,
1596     {
1597         SimpleStatement::Iteration(IterationStatement::DoWhile(
1598             Box::new(body.into()),
1599             Box::new(cond.into()),
1600         ))
1601     }
1602 }
1603 
1604 /// Expression statement.
1605 pub type ExprStatement = Option<Expr>;
1606 
1607 /// Selection statement.
1608 #[derive(Clone, Debug, PartialEq)]
1609 pub struct SelectionStatement {
1610     pub cond: Box<Expr>,
1611     pub body: Box<Statement>,
1612     // the else branch
1613     pub else_stmt: Option<Box<Statement>>,
1614 }
1615 
1616 /// Condition.
1617 #[derive(Clone, Debug, PartialEq)]
1618 pub enum Condition {
1619     Expr(Box<Expr>),
1620 }
1621 
1622 impl From<Expr> for Condition {
from(expr: Expr) -> Self1623     fn from(expr: Expr) -> Self {
1624         Condition::Expr(Box::new(expr))
1625     }
1626 }
1627 
1628 /// Switch statement.
1629 #[derive(Clone, Debug, PartialEq)]
1630 pub struct SwitchStatement {
1631     pub head: Box<Expr>,
1632     pub cases: Vec<Case>,
1633 }
1634 
1635 /// Case label statement.
1636 #[derive(Clone, Debug, PartialEq)]
1637 pub enum CaseLabel {
1638     Case(Box<Expr>),
1639     Def,
1640 }
1641 
1642 /// An individual case
1643 #[derive(Clone, Debug, PartialEq)]
1644 pub struct Case {
1645     pub label: CaseLabel,
1646     pub stmts: Vec<Statement>,
1647 }
1648 
1649 /// Iteration statement.
1650 #[derive(Clone, Debug, PartialEq)]
1651 pub enum IterationStatement {
1652     While(Condition, Box<Statement>),
1653     DoWhile(Box<Statement>, Box<Expr>),
1654     For(ForInitStatement, ForRestStatement, Box<Statement>),
1655 }
1656 
1657 /// For init statement.
1658 #[derive(Clone, Debug, PartialEq)]
1659 pub enum ForInitStatement {
1660     Expression(Option<Expr>),
1661     Declaration(Box<Declaration>),
1662 }
1663 
1664 /// For init statement.
1665 #[derive(Clone, Debug, PartialEq)]
1666 pub struct ForRestStatement {
1667     pub condition: Option<Condition>,
1668     pub post_expr: Option<Box<Expr>>,
1669 }
1670 
1671 /// Jump statement.
1672 #[derive(Clone, Debug, PartialEq)]
1673 pub enum JumpStatement {
1674     Continue,
1675     Break,
1676     Return(Option<Box<Expr>>),
1677     Discard,
1678 }
1679 
1680 trait NonEmptyExt<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>1681     fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>;
new(x: T) -> NonEmpty<T>1682     fn new(x: T) -> NonEmpty<T>;
1683 }
1684 
1685 impl<T> NonEmptyExt<T> for NonEmpty<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U>1686     fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U> {
1687         NonEmpty::from_non_empty_iter(self.into_iter().map(|x| f(s, &x))).unwrap()
1688     }
new(x: T) -> NonEmpty<T>1689     fn new(x: T) -> NonEmpty<T> {
1690         NonEmpty::from_non_empty_iter(vec![x].into_iter()).unwrap()
1691     }
1692 }
1693 
translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer1694 fn translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer {
1695     match i {
1696         syntax::Initializer::Simple(i) => {
1697             Initializer::Simple(Box::new(translate_expression(state, i)))
1698         }
1699         _ => panic!(),
1700     }
1701 }
1702 
translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration1703 fn translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration {
1704     let ty = d.ty.clone();
1705     let ty_def = match &ty.ty.ty {
1706         TypeSpecifierNonArray::Struct(s) => {
1707             let decl = SymDecl::Struct(lift(state, s));
1708             Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1709         }
1710         _ => None,
1711     };
1712 
1713     let ty_def = ty_def.expect("Must be type definition");
1714 
1715     Declaration::StructDefinition(ty_def)
1716 }
1717 
get_expr_index(e: &syntax::Expr) -> i321718 fn get_expr_index(e: &syntax::Expr) -> i32 {
1719     match e {
1720         syntax::Expr::IntConst(i) => *i,
1721         syntax::Expr::UIntConst(u) => *u as i32,
1722         syntax::Expr::FloatConst(f) => *f as i32,
1723         syntax::Expr::DoubleConst(f) => *f as i32,
1724         _ => panic!(),
1725     }
1726 }
1727 
translate_variable_declaration( state: &mut State, d: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1728 fn translate_variable_declaration(
1729     state: &mut State,
1730     d: &syntax::InitDeclaratorList,
1731     default_run_class: RunClass,
1732 ) -> Declaration {
1733     let mut ty = d.head.ty.clone();
1734     ty.ty.array_specifier = d.head.array_specifier.clone();
1735     let ty_def = match &ty.ty.ty {
1736         TypeSpecifierNonArray::Struct(s) => {
1737             let decl = SymDecl::Struct(lift(state, s));
1738             Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1739         }
1740         _ => None,
1741     };
1742 
1743     let mut ty: Type = lift(state, &d.head.ty);
1744     if let Some(array) = &d.head.array_specifier {
1745         ty.array_sizes = Some(Box::new(lift(state, array)))
1746     }
1747 
1748     let (sym, decl) = match d.head.name.as_ref() {
1749         Some(name) => {
1750             let mut storage = StorageClass::None;
1751             let mut interpolation = None;
1752             for qual in d
1753                 .head
1754                 .ty
1755                 .qualifier
1756                 .iter()
1757                 .flat_map(|x| x.qualifiers.0.iter())
1758             {
1759                 match qual {
1760                     syntax::TypeQualifierSpec::Storage(s) => match (&storage, s) {
1761                         (StorageClass::FragColor(..), syntax::StorageQualifier::Out) => {}
1762                         (StorageClass::Sampler(..), syntax::StorageQualifier::Uniform) => {}
1763                         (StorageClass::None, syntax::StorageQualifier::Out) => {
1764                             storage = StorageClass::Out;
1765                         }
1766                         (StorageClass::None, syntax::StorageQualifier::In) => {
1767                             storage = StorageClass::In;
1768                         }
1769                         (StorageClass::None, syntax::StorageQualifier::Uniform) => {
1770                             if ty.kind.is_sampler() {
1771                                 storage = StorageClass::Sampler(SamplerFormat::Unknown);
1772                             } else {
1773                                 storage = StorageClass::Uniform;
1774                             }
1775                         }
1776                         (StorageClass::None, syntax::StorageQualifier::Const) => {
1777                             storage = StorageClass::Const;
1778                         }
1779                         _ => panic!("bad storage {:?}", (storage, s)),
1780                     },
1781                     syntax::TypeQualifierSpec::Interpolation(i) => match (&interpolation, i) {
1782                         (None, i) => interpolation = Some(i.clone()),
1783                         _ => panic!("multiple interpolation"),
1784                     },
1785                     syntax::TypeQualifierSpec::Layout(l) => {
1786                         let mut loc = -1;
1787                         let mut index = -1;
1788                         for id in &l.ids {
1789                             match id {
1790                                 syntax::LayoutQualifierSpec::Identifier(ref key, None) => {
1791                                     match key.as_str() {
1792                                         "rgba8" => {
1793                                             storage = StorageClass::Sampler(SamplerFormat::RGBA8);
1794                                         }
1795                                         "rgba32f" => {
1796                                             storage = StorageClass::Sampler(SamplerFormat::RGBA32F);
1797                                         }
1798                                         "rgba32i" => {
1799                                             storage = StorageClass::Sampler(SamplerFormat::RGBA32I);
1800                                         }
1801                                         "r8" => {
1802                                             storage = StorageClass::Sampler(SamplerFormat::R8);
1803                                         }
1804                                         "rg8" => {
1805                                             storage = StorageClass::Sampler(SamplerFormat::RG8);
1806                                         }
1807                                         _ => {}
1808                                     }
1809                                 }
1810                                 syntax::LayoutQualifierSpec::Identifier(ref key, Some(ref e)) => {
1811                                     match key.as_str() {
1812                                         "location" => {
1813                                             loc = get_expr_index(e);
1814                                         }
1815                                         "index" => {
1816                                             index = get_expr_index(e);
1817                                         }
1818                                         _ => {}
1819                                     }
1820                                 }
1821                                 _ => {}
1822                             }
1823                         }
1824                         if index >= 0 {
1825                             assert!(loc == 0);
1826                             assert!(index <= 1);
1827                             assert!(storage == StorageClass::None);
1828                             storage = StorageClass::FragColor(index);
1829                         }
1830                     }
1831                     _ => {}
1832                 }
1833             }
1834             let decl = if state.in_function.is_some() {
1835                 let run_class = match storage {
1836                     StorageClass::Const => RunClass::Scalar,
1837                     StorageClass::None => default_run_class,
1838                     _ => panic!("bad local storage {:?}", storage),
1839                 };
1840                 SymDecl::Local(storage, ty.clone(), run_class)
1841             } else {
1842                 let run_class = match storage {
1843                     StorageClass::Const | StorageClass::Uniform | StorageClass::Sampler(..) => {
1844                         RunClass::Scalar
1845                     }
1846                     StorageClass::In | StorageClass::Out | StorageClass::FragColor(..)
1847                         if interpolation == Some(syntax::InterpolationQualifier::Flat) =>
1848                     {
1849                         RunClass::Scalar
1850                     }
1851                     _ => RunClass::Vector,
1852                 };
1853                 SymDecl::Global(storage, interpolation, ty.clone(), run_class)
1854             };
1855             (state.declare(name.as_str(), decl.clone()), decl)
1856         }
1857         None => panic!(),
1858     };
1859 
1860     let head = SingleDeclaration {
1861         qualifier: lift_type_qualifier_for_declaration(state, &d.head.ty.qualifier),
1862         name: sym,
1863         ty,
1864         ty_def,
1865         initializer: d
1866             .head
1867             .initializer
1868             .as_ref()
1869             .map(|x| translate_initializater(state, x)),
1870     };
1871 
1872     let tail = d
1873         .tail
1874         .iter()
1875         .map(|d| {
1876             if let Some(_array) = &d.ident.array_spec {
1877                 panic!("unhandled array")
1878             }
1879             state.declare(d.ident.ident.as_str(), decl.clone());
1880             SingleDeclarationNoType {
1881                 ident: d.ident.clone(),
1882                 initializer: d
1883                     .initializer
1884                     .as_ref()
1885                     .map(|x| translate_initializater(state, x)),
1886             }
1887         })
1888         .collect();
1889     Declaration::InitDeclaratorList(InitDeclaratorList { head, tail })
1890 }
1891 
translate_init_declarator_list( state: &mut State, l: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1892 fn translate_init_declarator_list(
1893     state: &mut State,
1894     l: &syntax::InitDeclaratorList,
1895     default_run_class: RunClass,
1896 ) -> Declaration {
1897     match &l.head.name {
1898         Some(_name) => translate_variable_declaration(state, l, default_run_class),
1899         None => translate_struct_declaration(state, &l.head),
1900     }
1901 }
1902 
translate_declaration( state: &mut State, d: &syntax::Declaration, default_run_class: RunClass, ) -> Declaration1903 fn translate_declaration(
1904     state: &mut State,
1905     d: &syntax::Declaration,
1906     default_run_class: RunClass,
1907 ) -> Declaration {
1908     match d {
1909         syntax::Declaration::Block(_) => panic!(), //Declaration::Block(..),
1910         syntax::Declaration::FunctionPrototype(p) => {
1911             Declaration::FunctionPrototype(translate_function_prototype(state, p))
1912         }
1913         syntax::Declaration::Global(ty, ids) => {
1914             // glsl non-es supports requalifying variables, but we don't yet.
1915             // However, we still want to allow global layout qualifiers for
1916             // KHR_advanced_blend_equation.
1917             if !ids.is_empty() {
1918                 panic!();
1919             }
1920             let _ = for qual in &ty.qualifiers {
1921                 match qual {
1922                     syntax::TypeQualifierSpec::Layout(l) => {
1923                         for id in &l.ids {
1924                             match id {
1925                                 syntax::LayoutQualifierSpec::Identifier(key, _) => {
1926                                     match key.as_str() {
1927                                         "blend_support_all_equations" => (),
1928                                         _ => panic!(),
1929                                     }
1930                                 }
1931                                 _ => panic!(),
1932                             }
1933                         }
1934                     }
1935                     syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Out) => (),
1936                     _ => panic!(),
1937                 }
1938             };
1939             Declaration::Global(lift_type_qualifier_for_declaration(state, &Some(ty.clone())).unwrap(), ids.clone())
1940         }
1941         syntax::Declaration::InitDeclaratorList(dl) => {
1942             translate_init_declarator_list(state, dl, default_run_class)
1943         }
1944         syntax::Declaration::Precision(p, ts) => Declaration::Precision(p.clone(), ts.clone()),
1945     }
1946 }
1947 
is_vector(ty: &Type) -> bool1948 fn is_vector(ty: &Type) -> bool {
1949     match ty.kind {
1950         TypeKind::Vec2
1951         | TypeKind::Vec3
1952         | TypeKind::Vec4
1953         | TypeKind::BVec2
1954         | TypeKind::BVec3
1955         | TypeKind::BVec4
1956         | TypeKind::IVec2
1957         | TypeKind::IVec3
1958         | TypeKind::IVec4 => ty.array_sizes == None,
1959         _ => false,
1960     }
1961 }
1962 
index_vector(ty: &Type) -> Option<TypeKind>1963 fn index_vector(ty: &Type) -> Option<TypeKind> {
1964     use TypeKind::*;
1965     if ty.array_sizes != None {
1966         return None;
1967     }
1968     Some(match ty.kind {
1969         Vec2 => Float,
1970         Vec3 => Float,
1971         Vec4 => Float,
1972         DVec2 => Double,
1973         DVec3 => Double,
1974         DVec4 => Double,
1975         BVec2 => Bool,
1976         BVec3 => Bool,
1977         BVec4 => Bool,
1978         IVec2 => Int,
1979         IVec3 => Int,
1980         IVec4 => Int,
1981         UVec2 => UInt,
1982         UVec3 => UInt,
1983         UVec4 => UInt,
1984         _ => return None,
1985     })
1986 
1987 }
1988 
index_matrix(ty: &Type) -> Option<TypeKind>1989 fn index_matrix(ty: &Type) -> Option<TypeKind> {
1990     use TypeKind::*;
1991     if ty.array_sizes != None {
1992         return None;
1993     }
1994     Some(match ty.kind {
1995         Mat2 => Vec2,
1996         Mat3 => Vec3,
1997         Mat4 => Vec4,
1998         Mat23 => Vec3,
1999         Mat24 => Vec4,
2000         Mat32 => Vec2,
2001         Mat34 => Vec4,
2002         Mat42 => Vec2,
2003         Mat43 => Vec3,
2004         DMat2 => DVec2,
2005         DMat3 => DVec3,
2006         DMat4 => DVec4,
2007         DMat23 => DVec3,
2008         DMat24 => DVec4,
2009         DMat32 => DVec2,
2010         DMat34 => DVec4,
2011         DMat42 => DVec2,
2012         DMat43 => DVec3,
2013         _ => return None,
2014     })
2015 }
2016 
is_ivec(ty: &Type) -> bool2017 fn is_ivec(ty: &Type) -> bool {
2018     match ty.kind {
2019         TypeKind::IVec2 | TypeKind::IVec3 | TypeKind::IVec4 => ty.array_sizes == None,
2020         _ => false,
2021     }
2022 }
2023 
can_implicitly_convert_to(src: &Type, dst: &Type) -> bool2024 fn can_implicitly_convert_to(src: &Type, dst: &Type) -> bool {
2025     // XXX: use an underlying type helper
2026     if src == &Type::new(TypeKind::Double) && dst == &Type::new(TypeKind::Float) {
2027         // We're not supposed to implicitly convert from double to float but glsl 4 has a bug
2028         // where it parses unannotated float constants as double.
2029         true
2030     } else if dst == &Type::new(TypeKind::Double) && src == &Type::new(TypeKind::Float) {
2031         true
2032     } else if (dst == &Type::new(TypeKind::Float) || dst == &Type::new(TypeKind::Double)) &&
2033         src == &Type::new(TypeKind::Int)
2034     {
2035         true
2036     } else if (dst == &Type::new(TypeKind::Vec2) || dst == &Type::new(TypeKind::DVec2)) &&
2037         src == &Type::new(TypeKind::IVec2)
2038     {
2039         true
2040     } else if dst == &Type::new(TypeKind::IVec2) &&
2041         (src == &Type::new(TypeKind::Vec2) || src == &Type::new(TypeKind::DVec2))
2042     {
2043         true
2044     } else {
2045         src.kind == dst.kind && src.array_sizes == dst.array_sizes
2046     }
2047 }
2048 
promoted_type(lhs: &Type, rhs: &Type) -> Type2049 fn promoted_type(lhs: &Type, rhs: &Type) -> Type {
2050     if lhs == &Type::new(TypeKind::Double) && rhs == &Type::new(TypeKind::Float) {
2051         Type::new(TypeKind::Double)
2052     } else if lhs == &Type::new(TypeKind::Float) && rhs == &Type::new(TypeKind::Double) {
2053         Type::new(TypeKind::Double)
2054     } else if lhs == &Type::new(TypeKind::Int) && rhs == &Type::new(TypeKind::Double) {
2055         Type::new(TypeKind::Double)
2056     } else if is_vector(&lhs) &&
2057         (rhs == &Type::new(TypeKind::Float) ||
2058          rhs == &Type::new(TypeKind::Double) ||
2059          rhs == &Type::new(TypeKind::Int))
2060     {
2061         // scalars promote to vectors
2062         lhs.clone()
2063     } else if is_vector(&rhs) &&
2064         (lhs == &Type::new(TypeKind::Float) ||
2065          lhs == &Type::new(TypeKind::Double) ||
2066          lhs == &Type::new(TypeKind::Int))
2067     {
2068         // scalars promote to vectors
2069         rhs.clone()
2070     } else if lhs == rhs {
2071         lhs.clone()
2072     } else if lhs.kind == rhs.kind {
2073         if lhs.array_sizes == rhs.array_sizes {
2074             // XXX: we need to be able to query the default precision here
2075             match (&lhs.precision, &rhs.precision) {
2076                 (Some(PrecisionQualifier::High), _) => lhs.clone(),
2077                 (_, Some(PrecisionQualifier::High)) => rhs.clone(),
2078                 (None, _) => lhs.clone(),
2079                 (_, None) => rhs.clone(),
2080                 _ => panic!("precision mismatch {:?} {:?}", lhs.precision, rhs.precision),
2081             }
2082         } else {
2083             panic!("array size mismatch")
2084         }
2085     } else {
2086         assert_eq!(lhs, rhs);
2087         lhs.clone()
2088     }
2089 }
2090 
is_output(expr: &Expr, state: &State) -> Option<SymRef>2091 pub fn is_output(expr: &Expr, state: &State) -> Option<SymRef> {
2092     match &expr.kind {
2093         ExprKind::Variable(i) => match state.sym(*i).decl {
2094             SymDecl::Global(storage, ..) => match storage {
2095                 StorageClass::In | StorageClass::Out => return Some(*i),
2096                 _ => {}
2097             },
2098             SymDecl::Local(..) => {}
2099             _ => panic!("should be variable"),
2100         },
2101         ExprKind::SwizzleSelector(e, ..) => {
2102             return is_output(e, state);
2103         }
2104         ExprKind::Bracket(e, ..) => {
2105             return is_output(e, state);
2106         }
2107         ExprKind::Dot(e, ..) => {
2108             return is_output(e, state);
2109         }
2110         _ => {}
2111     };
2112     None
2113 }
2114 
get_texel_fetch_offset( state: &State, sampler_expr: &Expr, uv_expr: &Expr, offset_expr: &Expr, ) -> Option<(SymRef, SymRef, i32, i32)>2115 pub fn get_texel_fetch_offset(
2116     state: &State,
2117     sampler_expr: &Expr,
2118     uv_expr: &Expr,
2119     offset_expr: &Expr,
2120 ) -> Option<(SymRef, SymRef, i32, i32)> {
2121     if let ExprKind::Variable(ref sampler) = &sampler_expr.kind {
2122         //if let ExprKind::Binary(BinaryOp::Add, ref lhs, ref rhs) = &uv_expr.kind {
2123         if let ExprKind::Variable(ref base) = &uv_expr.kind {
2124             if let ExprKind::FunCall(ref fun, ref args) = &offset_expr.kind {
2125                 if let FunIdentifier::Identifier(ref offset) = fun {
2126                     if state.sym(*offset).name == "ivec2" {
2127                         if let ExprKind::IntConst(ref x) = &args[0].kind {
2128                             if let ExprKind::IntConst(ref y) = &args[1].kind {
2129                                 return Some((*sampler, *base, *x, *y));
2130                             }
2131                         }
2132                     }
2133                 }
2134             }
2135         }
2136         //}
2137     }
2138     None
2139 }
2140 
make_const(t: TypeKind, v: i32) -> Expr2141 fn make_const(t: TypeKind, v: i32) -> Expr {
2142     Expr {
2143         kind: match t {
2144             TypeKind::Int => ExprKind::IntConst(v as _),
2145             TypeKind::UInt => ExprKind::UIntConst(v as _),
2146             TypeKind::Bool => ExprKind::BoolConst(v != 0),
2147             TypeKind::Float => ExprKind::FloatConst(v as _),
2148             TypeKind::Double => ExprKind::DoubleConst(v as _),
2149             _ => panic!("bad constant type"),
2150         },
2151         ty: Type::new(t),
2152     }
2153 }
2154 
2155 // Any parameters needing to convert to bool should just compare via != 0.
2156 // This ensures they get the proper all-1s pattern for C++ OpenCL vectors.
force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>)2157 fn force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>) {
2158     for e in params {
2159         if !e.ty.kind.is_bool() {
2160             let k = e.ty.kind;
2161             *e = Expr {
2162                 kind: ExprKind::Binary(
2163                     BinaryOp::NonEqual,
2164                     Box::new(e.clone()),
2165                     Box::new(make_const(k.to_scalar(), 0)),
2166                 ),
2167                 ty: Type::new(k.to_bool()),
2168             };
2169         }
2170     }
2171 }
2172 
2173 // Transform bool params to int, then mask off the low bit so they become 0 or 1.
2174 // C++ OpenCL vectors represent bool as all-1s patterns, which will erroneously
2175 // convert to -1 otherwise.
force_params_from_bool(state: &mut State, params: &mut Vec<Expr>)2176 fn force_params_from_bool(state: &mut State, params: &mut Vec<Expr>) {
2177     for e in params {
2178         if e.ty.kind.is_bool() {
2179             let k = e.ty.kind.to_int();
2180             let sym = state.lookup(k.glsl_primitive_type_name().unwrap()).unwrap();
2181             *e = Expr {
2182                 kind: ExprKind::Binary(
2183                     BinaryOp::BitAnd,
2184                     Box::new(Expr {
2185                         kind: ExprKind::FunCall(
2186                             FunIdentifier::Identifier(sym),
2187                             vec![e.clone()],
2188                         ),
2189                         ty: Type::new(k),
2190                     }),
2191                     Box::new(make_const(TypeKind::Int, 1)),
2192                 ),
2193                 ty: Type::new(k),
2194             };
2195         }
2196     }
2197 }
2198 
translate_expression(state: &mut State, e: &syntax::Expr) -> Expr2199 fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
2200     match e {
2201         syntax::Expr::Variable(i) => {
2202             let sym = match state.lookup(i.as_str()) {
2203                 Some(sym) => sym,
2204                 None => panic!("missing declaration {}", i.as_str()),
2205             };
2206             let ty = match &state.sym(sym).decl {
2207                 SymDecl::Global(_, _, ty, _) => {
2208                     let mut globals = state.used_globals.borrow_mut();
2209                     if !globals.contains(&sym) {
2210                         globals.push(sym);
2211                     }
2212                     ty.clone()
2213                 }
2214                 SymDecl::Local(_, ty, _) => ty.clone(),
2215                 _ => panic!("bad variable type"),
2216             };
2217             Expr {
2218                 kind: ExprKind::Variable(sym),
2219                 ty,
2220             }
2221         }
2222         syntax::Expr::Assignment(lhs, op, rhs) => {
2223             let lhs = Box::new(translate_expression(state, lhs));
2224             let rhs = Box::new(translate_expression(state, rhs));
2225             let ty = if op == &AssignmentOp::Mult {
2226                 if lhs.ty.kind == TypeKind::Vec4 && rhs.ty.kind == TypeKind::Float {
2227                     lhs.ty.clone()
2228                 } else {
2229                     promoted_type(&lhs.ty, &rhs.ty)
2230                 }
2231             } else {
2232                 promoted_type(&lhs.ty, &rhs.ty)
2233             };
2234             if let Some(global) = is_output(&lhs, state) {
2235                 let mut globals = state.modified_globals.borrow_mut();
2236                 if !globals.contains(&global) {
2237                     globals.push(global);
2238                 }
2239                 if global == state.clip_dist_sym {
2240                     if let ExprKind::Bracket(_, idx) = &lhs.kind {
2241                         // Get the constant array index used for gl_ClipDistance and add it to the used mask.
2242                         let idx = match idx.kind {
2243                             ExprKind::IntConst(idx) => idx,
2244                             ExprKind::UIntConst(idx) => idx as i32,
2245                             _ => panic!("bad index for gl_ClipDistance"),
2246                         };
2247                         assert!(idx >= 0 && idx < 4);
2248                         state.used_clip_dist |= 1 << idx;
2249                     }
2250                 }
2251             }
2252             Expr {
2253                 kind: ExprKind::Assignment(lhs, op.clone(), rhs),
2254                 ty,
2255             }
2256         }
2257         syntax::Expr::Binary(op, lhs, rhs) => {
2258             let lhs = Box::new(translate_expression(state, lhs));
2259             let rhs = Box::new(translate_expression(state, rhs));
2260             let ty = match op {
2261                 BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
2262                     // comparison operators have a bool result
2263                     Type::new(TypeKind::Bool)
2264                 }
2265                 BinaryOp::Mult => {
2266                     match (lhs.ty.kind, rhs.ty.kind) {
2267                         (TypeKind::Mat2, TypeKind::Vec2) |
2268                         (TypeKind::Mat3, TypeKind::Vec3) |
2269                         (TypeKind::Mat3, TypeKind::Mat3) |
2270                         (TypeKind::Mat3, TypeKind::Mat43) |
2271                         (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(),
2272                         (TypeKind::Mat43, TypeKind::Vec4) => Type::new(TypeKind::Vec3),
2273                         (TypeKind::Mat2, TypeKind::Float) |
2274                         (TypeKind::Mat3, TypeKind::Float) |
2275                         (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(),
2276                         _ => promoted_type(&lhs.ty, &rhs.ty),
2277                     }
2278                 }
2279                 _ => promoted_type(&lhs.ty, &rhs.ty),
2280             };
2281 
2282             Expr {
2283                 kind: ExprKind::Binary(op.clone(), lhs, rhs),
2284                 ty,
2285             }
2286         }
2287         syntax::Expr::Unary(op, e) => {
2288             let e = Box::new(translate_expression(state, e));
2289             let ty = e.ty.clone();
2290             Expr {
2291                 kind: ExprKind::Unary(op.clone(), e),
2292                 ty,
2293             }
2294         }
2295         syntax::Expr::BoolConst(b) => Expr {
2296             kind: ExprKind::BoolConst(*b),
2297             ty: Type::new(TypeKind::Bool),
2298         },
2299         syntax::Expr::Comma(lhs, rhs) => {
2300             let lhs = Box::new(translate_expression(state, lhs));
2301             let rhs = Box::new(translate_expression(state, rhs));
2302             assert_eq!(lhs.ty, rhs.ty);
2303             let ty = lhs.ty.clone();
2304             Expr {
2305                 kind: ExprKind::Comma(lhs, rhs),
2306                 ty,
2307             }
2308         }
2309         syntax::Expr::DoubleConst(d) => Expr {
2310             kind: ExprKind::DoubleConst(*d),
2311             ty: Type::new(TypeKind::Double),
2312         },
2313         syntax::Expr::FloatConst(f) => Expr {
2314             kind: ExprKind::FloatConst(*f),
2315             ty: Type::new(TypeKind::Float),
2316         },
2317         syntax::Expr::FunCall(fun, params) => {
2318             let ret_ty: Type;
2319             let mut params: Vec<Expr> = params
2320                 .iter()
2321                 .map(|x| translate_expression(state, x))
2322                 .collect();
2323             Expr {
2324                 kind: ExprKind::FunCall(
2325                     match fun {
2326                         syntax::FunIdentifier::Identifier(i) => {
2327                             let name = i.as_str();
2328                             if name == "texelFetchOffset" && params.len() >= 4 {
2329                                 if let Some((sampler, base, x, y)) = get_texel_fetch_offset(
2330                                     state, &params[0], &params[1], &params[3],
2331                                 ) {
2332                                     if let Some(offsets) =
2333                                         state.texel_fetches.get_mut(&(sampler, base))
2334                                     {
2335                                         offsets.add_offset(x, y);
2336                                     } else {
2337                                         state
2338                                             .texel_fetches
2339                                             .insert((sampler, base), TexelFetchOffsets::new(x, y));
2340                                     }
2341                                 }
2342                             } else if name == "swgl_stepInterp" {
2343                                 let mut globals = state.modified_globals.borrow_mut();
2344                                 for (i, sym) in state.syms.iter().enumerate() {
2345                                     match &sym.borrow().decl {
2346                                         SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => {
2347                                             let symref = SymRef(i as u32);
2348                                             if !globals.contains(&symref) {
2349                                                 globals.push(symref);
2350                                             }
2351                                         }
2352                                         _ => {}
2353                                     }
2354                                 }
2355                             }
2356                             let sym = match state.lookup(name) {
2357                                 Some(s) => s,
2358                                 None => panic!("missing symbol {}", name),
2359                             };
2360                             // Force any boolean basic type constructors to generate correct
2361                             // bit patterns.
2362                             if let Some(t) = TypeKind::from_glsl_primitive_type_name(name) {
2363                                 if t.is_bool() {
2364                                     force_params_to_bool(state, &mut params);
2365                                 } else {
2366                                     force_params_from_bool(state, &mut params);
2367                                 }
2368                             }
2369                             match &state.sym(sym).decl {
2370                                 SymDecl::NativeFunction(fn_ty, _, _) => {
2371                                     // Search for a signature where all parameter types are
2372                                     // compatible. If there are many compatible signatures,
2373                                     // then choose the one with the most exact matches.
2374                                     // This is an approximation of the algorith described in
2375                                     // the "Function Definitions" section of the spec.
2376                                     let mut ret = None;
2377                                     let mut best_score = 0;
2378                                     'next_sig: for sig in &fn_ty.signatures {
2379                                         let mut score = 0;
2380                                         for (e, p) in params.iter().zip(sig.params.iter()) {
2381                                             if e.ty == *p {
2382                                                 score += 1;
2383                                             } else if !can_implicitly_convert_to(&e.ty, p) {
2384                                                 continue 'next_sig;
2385                                             }
2386                                         }
2387                                         if score >= best_score {
2388                                             ret = Some(sig.ret.clone());
2389                                             best_score = score;
2390                                             // If all parameters match exactly, then there
2391                                             // is no need to search for other matches.
2392                                             if best_score >= params.len() {
2393                                                 break;
2394                                             }
2395                                         }
2396                                     }
2397                                     ret_ty = match ret {
2398                                         Some(t) => t,
2399                                         None => {
2400                                             dbg!(&fn_ty.signatures);
2401                                             dbg!(params.iter().map(|p| p).collect::<Vec<_>>());
2402                                             panic!("no matching func {}", i.as_str())
2403                                         }
2404                                     };
2405                                 }
2406                                 SymDecl::UserFunction(fd, _) => {
2407                                     let mut globals = state.modified_globals.borrow_mut();
2408                                     for global in &fd.globals {
2409                                         if !globals.contains(global) {
2410                                             globals.push(*global);
2411                                         }
2412                                     }
2413                                     let mut matching = true;
2414                                     for (e, p) in params.iter().zip(fd.prototype.parameters.iter())
2415                                     {
2416                                         matching &= match p {
2417                                             FunctionParameterDeclaration::Named(q, d) => {
2418                                                 match q {
2419                                                     Some(ParameterQualifier::InOut)
2420                                                     | Some(ParameterQualifier::Out) => {
2421                                                         if let Some(global) = is_output(e, state) {
2422                                                             if !globals.contains(&global) {
2423                                                                 globals.push(global);
2424                                                             }
2425                                                         }
2426                                                     }
2427                                                     _ => {}
2428                                                 }
2429                                                 can_implicitly_convert_to(&e.ty, &d.ty)
2430                                             }
2431                                             FunctionParameterDeclaration::Unnamed(..) => panic!(),
2432                                         };
2433                                     }
2434                                     assert!(matching);
2435                                     ret_ty = fd.prototype.ty.clone();
2436                                 }
2437                                 SymDecl::Struct(_) => ret_ty = Type::new(TypeKind::Struct(sym)),
2438                                 _ => panic!("can only call functions"),
2439                             };
2440                             FunIdentifier::Identifier(sym)
2441                         }
2442                         // array constructor
2443                         syntax::FunIdentifier::Expr(e) => {
2444                             let ty = match &**e {
2445                                 syntax::Expr::Bracket(i, array) => {
2446                                     let kind = match &**i {
2447                                         syntax::Expr::Variable(i) => match i.as_str() {
2448                                             "vec4" => TypeKind::Vec4,
2449                                             "vec2" => TypeKind::Vec2,
2450                                             "int" => TypeKind::Int,
2451                                             _ => panic!("unexpected type constructor {:?}", i),
2452                                         },
2453                                         _ => panic!(),
2454                                     };
2455 
2456                                     Type {
2457                                         kind,
2458                                         precision: None,
2459                                         array_sizes: Some(Box::new(lift(state, array))),
2460                                     }
2461                                 }
2462                                 _ => panic!(),
2463                             };
2464                             ret_ty = ty.clone();
2465 
2466                             FunIdentifier::Constructor(ty)
2467                         }
2468                     },
2469                     params,
2470                 ),
2471                 ty: ret_ty,
2472             }
2473         }
2474         syntax::Expr::IntConst(i) => Expr {
2475             kind: ExprKind::IntConst(*i),
2476             ty: Type::new(TypeKind::Int),
2477         },
2478         syntax::Expr::UIntConst(u) => Expr {
2479             kind: ExprKind::UIntConst(*u),
2480             ty: Type::new(TypeKind::UInt),
2481         },
2482         syntax::Expr::PostDec(e) => {
2483             let e = Box::new(translate_expression(state, e));
2484             let ty = e.ty.clone();
2485             Expr {
2486                 kind: ExprKind::PostDec(e),
2487                 ty,
2488             }
2489         }
2490         syntax::Expr::PostInc(e) => {
2491             let e = Box::new(translate_expression(state, e));
2492             let ty = e.ty.clone();
2493             Expr {
2494                 kind: ExprKind::PostInc(e),
2495                 ty,
2496             }
2497         }
2498         syntax::Expr::Ternary(cond, lhs, rhs) => {
2499             let cond = Box::new(translate_expression(state, cond));
2500             let lhs = Box::new(translate_expression(state, lhs));
2501             let rhs = Box::new(translate_expression(state, rhs));
2502             let ty = promoted_type(&lhs.ty, &rhs.ty);
2503             Expr {
2504                 kind: ExprKind::Ternary(cond, lhs, rhs),
2505                 ty,
2506             }
2507         }
2508         syntax::Expr::Dot(e, i) => {
2509             let e = Box::new(translate_expression(state, e));
2510             let ty = e.ty.clone();
2511             let ivec = is_ivec(&ty);
2512             if is_vector(&ty) {
2513                 let ty = Type::new(match i.as_str().len() {
2514                     1 => {
2515                         if ivec {
2516                             TypeKind::Int
2517                         } else {
2518                             TypeKind::Float
2519                         }
2520                     }
2521                     2 => {
2522                         if ivec {
2523                             TypeKind::IVec2
2524                         } else {
2525                             TypeKind::Vec2
2526                         }
2527                     }
2528                     3 => {
2529                         if ivec {
2530                             TypeKind::IVec3
2531                         } else {
2532                             TypeKind::Vec3
2533                         }
2534                     }
2535                     4 => {
2536                         if ivec {
2537                             TypeKind::IVec4
2538                         } else {
2539                             TypeKind::Vec4
2540                         }
2541                     }
2542                     _ => panic!(),
2543                 });
2544 
2545                 let sel = SwizzleSelector::parse(i.as_str());
2546 
2547                 Expr {
2548                     kind: ExprKind::SwizzleSelector(e, sel),
2549                     ty,
2550                 }
2551             } else {
2552                 match ty.kind {
2553                     TypeKind::Struct(s) => {
2554                         let sym = state.sym(s);
2555                         let fields = match &sym.decl {
2556                             SymDecl::Struct(fields) => fields,
2557                             _ => panic!("expected struct"),
2558                         };
2559                         let field = fields
2560                             .fields
2561                             .iter()
2562                             .find(|x| &x.name == i)
2563                             .expect(&format!("missing field `{}` in `{}`", i, sym.name));
2564                         Expr {
2565                             kind: ExprKind::Dot(e, i.clone()),
2566                             ty: field.ty.clone(),
2567                         }
2568                     }
2569                     _ => panic!("expected struct found {:#?} {:#?}", e, ty),
2570                 }
2571             }
2572         }
2573         syntax::Expr::Bracket(e, specifier) => {
2574             let e = Box::new(translate_expression(state, e));
2575             let ty = if let Some(ty) = index_vector(&e.ty) {
2576                 Type::new(ty)
2577             } else if let Some(ty) = index_matrix(&e.ty) {
2578                 Type::new(ty)
2579             } else {
2580                 let a = match &e.ty.array_sizes {
2581                     Some(a) => {
2582                         let mut a = *a.clone();
2583                         a.sizes.pop();
2584                         if a.sizes.len() == 0 {
2585                             None
2586                         } else {
2587                             Some(Box::new(a))
2588                         }
2589                     }
2590                     _ => panic!("{:#?}", e),
2591                 };
2592                 Type {
2593                     kind: e.ty.kind.clone(),
2594                     precision: e.ty.precision.clone(),
2595                     array_sizes: a,
2596                 }
2597             };
2598             let indx = match specifier {
2599                 ArraySpecifier::Unsized => panic!("need expression"),
2600                 ArraySpecifier::ExplicitlySized(e) => translate_expression(state, e),
2601             };
2602             Expr {
2603                 kind: ExprKind::Bracket(e, Box::new(indx)),
2604                 ty,
2605             }
2606         }
2607     }
2608 }
2609 
translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement2610 fn translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement {
2611     let mut cases = Vec::new();
2612 
2613     let mut case = None;
2614     for stmt in &s.body {
2615         match stmt {
2616             syntax::Statement::Simple(s) => match &**s {
2617                 syntax::SimpleStatement::CaseLabel(label) => {
2618                     match case.take() {
2619                         Some(case) => cases.push(case),
2620                         _ => {}
2621                     }
2622                     case = Some(Case {
2623                         label: translate_case(state, &label),
2624                         stmts: Vec::new(),
2625                     })
2626                 }
2627                 _ => match case {
2628                     Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2629                     _ => panic!("switch must start with case"),
2630                 },
2631             },
2632             _ => match case {
2633                 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2634                 _ => panic!("switch must start with case"),
2635             },
2636         }
2637     }
2638     match case.take() {
2639         Some(case) => cases.push(case),
2640         _ => {}
2641     }
2642     SwitchStatement {
2643         head: Box::new(translate_expression(state, &s.head)),
2644         cases,
2645     }
2646 }
2647 
translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement2648 fn translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement {
2649     match s {
2650         syntax::JumpStatement::Break => JumpStatement::Break,
2651         syntax::JumpStatement::Continue => JumpStatement::Continue,
2652         syntax::JumpStatement::Discard => JumpStatement::Discard,
2653         syntax::JumpStatement::Return(e) => {
2654             JumpStatement::Return(e.as_ref().map(|e| Box::new(translate_expression(state, e))))
2655         }
2656     }
2657 }
2658 
translate_condition(state: &mut State, c: &syntax::Condition) -> Condition2659 fn translate_condition(state: &mut State, c: &syntax::Condition) -> Condition {
2660     match c {
2661         syntax::Condition::Expr(e) => Condition::Expr(Box::new(translate_expression(state, e))),
2662         _ => panic!(),
2663     }
2664 }
2665 
translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement2666 fn translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement {
2667     match s {
2668         syntax::ForInitStatement::Expression(e) => {
2669             ForInitStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2670         }
2671         syntax::ForInitStatement::Declaration(d) => ForInitStatement::Declaration(Box::new(
2672             translate_declaration(state, d, RunClass::Scalar),
2673         )),
2674     }
2675 }
2676 
translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement2677 fn translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement {
2678     ForRestStatement {
2679         condition: s.condition.as_ref().map(|c| translate_condition(state, c)),
2680         post_expr: s
2681             .post_expr
2682             .as_ref()
2683             .map(|e| Box::new(translate_expression(state, e))),
2684     }
2685 }
2686 
translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement2687 fn translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement {
2688     match s {
2689         syntax::IterationStatement::While(cond, s) => IterationStatement::While(
2690             translate_condition(state, cond),
2691             Box::new(translate_statement(state, s)),
2692         ),
2693         syntax::IterationStatement::For(init, rest, s) => IterationStatement::For(
2694             translate_for_init(state, init),
2695             translate_for_rest(state, rest),
2696             Box::new(translate_statement(state, s)),
2697         ),
2698         syntax::IterationStatement::DoWhile(s, e) => IterationStatement::DoWhile(
2699             Box::new(translate_statement(state, s)),
2700             Box::new(translate_expression(state, e)),
2701         ),
2702     }
2703 }
2704 
translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel2705 fn translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel {
2706     match c {
2707         syntax::CaseLabel::Def => CaseLabel::Def,
2708         syntax::CaseLabel::Case(e) => CaseLabel::Case(Box::new(translate_expression(state, e))),
2709     }
2710 }
2711 
translate_selection_rest( state: &mut State, s: &syntax::SelectionRestStatement, ) -> (Box<Statement>, Option<Box<Statement>>)2712 fn translate_selection_rest(
2713     state: &mut State,
2714     s: &syntax::SelectionRestStatement,
2715 ) -> (Box<Statement>, Option<Box<Statement>>) {
2716     match s {
2717         syntax::SelectionRestStatement::Statement(s) => {
2718             (Box::new(translate_statement(state, s)), None)
2719         }
2720         syntax::SelectionRestStatement::Else(if_body, rest) => (
2721             Box::new(translate_statement(state, if_body)),
2722             Some(Box::new(translate_statement(state, rest))),
2723         ),
2724     }
2725 }
2726 
translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement2727 fn translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement {
2728     let cond = Box::new(translate_expression(state, &s.cond));
2729     let (body, else_stmt) = translate_selection_rest(state, &s.rest);
2730     SelectionStatement {
2731         cond,
2732         body,
2733         else_stmt,
2734     }
2735 }
2736 
translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement2737 fn translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement {
2738     match s {
2739         syntax::SimpleStatement::Declaration(d) => {
2740             SimpleStatement::Declaration(translate_declaration(state, d, RunClass::Unknown))
2741         }
2742         syntax::SimpleStatement::Expression(e) => {
2743             SimpleStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2744         }
2745         syntax::SimpleStatement::Iteration(i) => {
2746             SimpleStatement::Iteration(translate_iteration(state, i))
2747         }
2748         syntax::SimpleStatement::Selection(s) => {
2749             SimpleStatement::Selection(translate_selection(state, s))
2750         }
2751         syntax::SimpleStatement::Jump(j) => SimpleStatement::Jump(translate_jump(state, j)),
2752         syntax::SimpleStatement::Switch(s) => SimpleStatement::Switch(translate_switch(state, s)),
2753         syntax::SimpleStatement::CaseLabel(_) => panic!("should be handled by translate_switch"),
2754     }
2755 }
2756 
translate_statement(state: &mut State, s: &syntax::Statement) -> Statement2757 fn translate_statement(state: &mut State, s: &syntax::Statement) -> Statement {
2758     match s {
2759         syntax::Statement::Compound(s) => {
2760             Statement::Compound(Box::new(translate_compound_statement(state, s)))
2761         }
2762         syntax::Statement::Simple(s) => {
2763             Statement::Simple(Box::new(translate_simple_statement(state, s)))
2764         }
2765     }
2766 }
2767 
translate_compound_statement( state: &mut State, cs: &syntax::CompoundStatement, ) -> CompoundStatement2768 fn translate_compound_statement(
2769     state: &mut State,
2770     cs: &syntax::CompoundStatement,
2771 ) -> CompoundStatement {
2772     CompoundStatement {
2773         statement_list: cs
2774             .statement_list
2775             .iter()
2776             .map(|x| translate_statement(state, x))
2777             .collect(),
2778     }
2779 }
2780 
translate_function_parameter_declaration( state: &mut State, p: &syntax::FunctionParameterDeclaration, index: usize, ) -> FunctionParameterDeclaration2781 fn translate_function_parameter_declaration(
2782     state: &mut State,
2783     p: &syntax::FunctionParameterDeclaration,
2784     index: usize,
2785 ) -> FunctionParameterDeclaration {
2786     match p {
2787         syntax::FunctionParameterDeclaration::Named(qual, p) => {
2788             let mut ty: Type = lift(state, &p.ty);
2789             if let Some(a) = &p.ident.array_spec {
2790                 ty.array_sizes = Some(Box::new(lift(state, a)));
2791             }
2792 
2793             ty.precision = get_precision(qual);
2794 
2795             let decl = SymDecl::Local(
2796                 StorageClass::None,
2797                 ty.clone(),
2798                 RunClass::Dependent(1 << index),
2799             );
2800             let d = FunctionParameterDeclarator {
2801                 ty,
2802                 name: p.ident.ident.clone(),
2803                 sym: state.declare(p.ident.ident.as_str(), decl),
2804             };
2805             FunctionParameterDeclaration::Named(lift_type_qualifier_for_parameter(state, qual), d)
2806         }
2807         syntax::FunctionParameterDeclaration::Unnamed(qual, p) => {
2808             FunctionParameterDeclaration::Unnamed(
2809                 lift_type_qualifier_for_parameter(state, qual),
2810                 p.clone(),
2811             )
2812         }
2813     }
2814 }
2815 
translate_prototype( state: &mut State, cs: &syntax::FunctionPrototype, ) -> (FunctionPrototype, SymRef)2816 fn translate_prototype(
2817     state: &mut State,
2818     cs: &syntax::FunctionPrototype,
2819 ) -> (FunctionPrototype, SymRef) {
2820     let prototype = FunctionPrototype {
2821         ty: lift(state, &cs.ty),
2822         name: cs.name.clone(),
2823         parameters: cs
2824             .parameters
2825             .iter()
2826             .enumerate()
2827             .map(|(i, x)| translate_function_parameter_declaration(state, x, i))
2828             .collect(),
2829     };
2830     let sym = if let Some(sym) = state.lookup(prototype.name.as_str()) {
2831         match &state.sym(sym).decl {
2832             SymDecl::UserFunction(..) => {}
2833             _ => panic!(
2834                 "prototype conflicts with existing symbol: {}",
2835                 prototype.name.as_str()
2836             ),
2837         }
2838         sym
2839     } else {
2840         let pfd = Rc::new(FunctionDefinition {
2841             prototype: prototype.clone(),
2842             body: CompoundStatement::new(),
2843             globals: Vec::new(),
2844             texel_fetches: HashMap::new(),
2845         });
2846         state.declare(
2847             prototype.name.as_str(),
2848             SymDecl::UserFunction(pfd, RunClass::Unknown),
2849         )
2850     };
2851     (prototype, sym)
2852 }
2853 
translate_function_prototype( state: &mut State, prototype: &syntax::FunctionPrototype, ) -> FunctionPrototype2854 fn translate_function_prototype(
2855     state: &mut State,
2856     prototype: &syntax::FunctionPrototype,
2857 ) -> FunctionPrototype {
2858     let (prototype, _) = translate_prototype(state, prototype);
2859     prototype
2860 }
2861 
translate_function_definition( state: &mut State, sfd: &syntax::FunctionDefinition, ) -> Rc<FunctionDefinition>2862 fn translate_function_definition(
2863     state: &mut State,
2864     sfd: &syntax::FunctionDefinition,
2865 ) -> Rc<FunctionDefinition> {
2866     let (prototype, sym) = translate_prototype(state, &sfd.prototype);
2867 
2868     state.push_scope(prototype.name.as_str().into());
2869     state.in_function = Some(sym);
2870     state.modified_globals.get_mut().clear();
2871     state.texel_fetches.clear();
2872     let body = translate_compound_statement(state, &sfd.statement);
2873     let mut globals = Vec::new();
2874     mem::swap(&mut globals, state.modified_globals.get_mut());
2875     let mut texel_fetches = HashMap::new();
2876     mem::swap(&mut texel_fetches, &mut state.texel_fetches);
2877     state.in_function = None;
2878     state.pop_scope();
2879 
2880     let fd = Rc::new(FunctionDefinition {
2881         prototype,
2882         body,
2883         globals,
2884         texel_fetches,
2885     });
2886     state.sym_mut(sym).decl = SymDecl::UserFunction(fd.clone(), RunClass::Unknown);
2887     fd
2888 }
2889 
translate_external_declaration( state: &mut State, ed: &syntax::ExternalDeclaration, ) -> ExternalDeclaration2890 fn translate_external_declaration(
2891     state: &mut State,
2892     ed: &syntax::ExternalDeclaration,
2893 ) -> ExternalDeclaration {
2894     match ed {
2895         syntax::ExternalDeclaration::Declaration(d) => {
2896             ExternalDeclaration::Declaration(translate_declaration(state, d, RunClass::Unknown))
2897         }
2898         syntax::ExternalDeclaration::FunctionDefinition(fd) => {
2899             ExternalDeclaration::FunctionDefinition(translate_function_definition(state, fd))
2900         }
2901         syntax::ExternalDeclaration::Preprocessor(p) => {
2902             ExternalDeclaration::Preprocessor(p.clone())
2903         }
2904     }
2905 }
2906 
declare_function_ext( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, run_class: RunClass, )2907 fn declare_function_ext(
2908     state: &mut State,
2909     name: &str,
2910     cxx_name: Option<&'static str>,
2911     ret: Type,
2912     params: Vec<Type>,
2913     run_class: RunClass,
2914 ) {
2915     let sig = FunctionSignature { ret, params };
2916     match state.lookup_sym_mut(name) {
2917         Some(Symbol {
2918             decl: SymDecl::NativeFunction(f, ..),
2919             ..
2920         }) => f.signatures.push(sig),
2921         None => {
2922             state.declare(
2923                 name,
2924                 SymDecl::NativeFunction(
2925                     FunctionType {
2926                         signatures: NonEmpty::new(sig),
2927                     },
2928                     cxx_name,
2929                     run_class,
2930                 ),
2931             );
2932         }
2933         _ => panic!("overloaded function name {}", name),
2934     }
2935     //state.declare(name, Type::Function(FunctionType{ v}))
2936 }
2937 
declare_function( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, )2938 fn declare_function(
2939     state: &mut State,
2940     name: &str,
2941     cxx_name: Option<&'static str>,
2942     ret: Type,
2943     params: Vec<Type>,
2944 ) {
2945     declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown)
2946 }
2947 
ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit2948 pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit {
2949     // global scope
2950     state.push_scope("global".into());
2951     use TypeKind::*;
2952     declare_function(
2953         state,
2954         "vec2",
2955         Some("make_vec2"),
2956         Type::new(Vec2),
2957         vec![Type::new(Float)],
2958     );
2959     declare_function(
2960         state,
2961         "vec2",
2962         Some("make_vec2"),
2963         Type::new(Vec2),
2964         vec![Type::new(Float), Type::new(Float)],
2965     );
2966     declare_function(
2967         state,
2968         "vec2",
2969         Some("make_vec2"),
2970         Type::new(Vec2),
2971         vec![Type::new(IVec2)],
2972     );
2973     declare_function(
2974         state,
2975         "vec2",
2976         Some("make_vec2"),
2977         Type::new(Vec2),
2978         vec![Type::new(IVec3)],
2979     );
2980     declare_function(
2981         state,
2982         "vec3",
2983         Some("make_vec3"),
2984         Type::new(Vec3),
2985         vec![Type::new(Float), Type::new(Float), Type::new(Float)],
2986     );
2987     declare_function(
2988         state,
2989         "vec3",
2990         Some("make_vec3"),
2991         Type::new(Vec3),
2992         vec![Type::new(Float)],
2993     );
2994     declare_function(
2995         state,
2996         "vec3",
2997         Some("make_vec3"),
2998         Type::new(Vec3),
2999         vec![Type::new(Vec2), Type::new(Float)],
3000     );
3001     declare_function(
3002         state,
3003         "vec4",
3004         Some("make_vec4"),
3005         Type::new(Vec4),
3006         vec![Type::new(Float)],
3007     );
3008     declare_function(
3009         state,
3010         "vec4",
3011         Some("make_vec4"),
3012         Type::new(Vec4),
3013         vec![Type::new(Vec3), Type::new(Float)],
3014     );
3015     declare_function(
3016         state,
3017         "vec4",
3018         Some("make_vec4"),
3019         Type::new(Vec4),
3020         vec![
3021             Type::new(Float),
3022             Type::new(Float),
3023             Type::new(Float),
3024             Type::new(Float),
3025         ],
3026     );
3027     declare_function(
3028         state,
3029         "vec4",
3030         Some("make_vec4"),
3031         Type::new(Vec4),
3032         vec![Type::new(Vec2), Type::new(Float), Type::new(Float)],
3033     );
3034     declare_function(
3035         state,
3036         "vec4",
3037         Some("make_vec4"),
3038         Type::new(Vec4),
3039         vec![Type::new(Vec2), Type::new(Vec2)],
3040     );
3041     declare_function(
3042         state,
3043         "vec4",
3044         Some("make_vec4"),
3045         Type::new(Vec4),
3046         vec![Type::new(Float), Type::new(Float), Type::new(Vec2)],
3047     );
3048     declare_function(
3049         state,
3050         "vec4",
3051         Some("make_vec4"),
3052         Type::new(Vec4),
3053         vec![Type::new(Vec4)],
3054     );
3055     declare_function(
3056         state,
3057         "vec4",
3058         Some("make_vec4"),
3059         Type::new(Vec4),
3060         vec![Type::new(IVec4)],
3061     );
3062 
3063     declare_function(
3064         state,
3065         "bvec2",
3066         Some("make_bvec2"),
3067         Type::new(BVec2),
3068         vec![Type::new(Bool)],
3069     );
3070     declare_function(
3071         state,
3072         "bvec3",
3073         Some("make_bvec3"),
3074         Type::new(BVec3),
3075         vec![Type::new(Bool)],
3076     );
3077     declare_function(
3078         state,
3079         "bvec4",
3080         Some("make_bvec4"),
3081         Type::new(BVec4),
3082         vec![Type::new(Bool)],
3083     );
3084     declare_function(
3085         state,
3086         "bvec4",
3087         Some("make_bvec4"),
3088         Type::new(BVec4),
3089         vec![Type::new(BVec2), Type::new(BVec2)],
3090     );
3091     declare_function(
3092         state,
3093         "bvec4",
3094         Some("make_bvec4"),
3095         Type::new(BVec4),
3096         vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)],
3097     );
3098     declare_function(
3099         state,
3100         "int",
3101         Some("make_int"),
3102         Type::new(Int),
3103         vec![Type::new(Float)],
3104     );
3105     declare_function(
3106         state,
3107         "float",
3108         Some("make_float"),
3109         Type::new(Float),
3110         vec![Type::new(Float)],
3111     );
3112     declare_function(
3113         state,
3114         "float",
3115         Some("make_float"),
3116         Type::new(Float),
3117         vec![Type::new(Int)],
3118     );
3119     declare_function(
3120         state,
3121         "int",
3122         Some("make_int"),
3123         Type::new(Int),
3124         vec![Type::new(UInt)],
3125     );
3126     declare_function(
3127         state,
3128         "uint",
3129         Some("make_uint"),
3130         Type::new(UInt),
3131         vec![Type::new(Float)],
3132     );
3133     declare_function(
3134         state,
3135         "uint",
3136         Some("make_uint"),
3137         Type::new(UInt),
3138         vec![Type::new(Int)],
3139     );
3140     declare_function(
3141         state,
3142         "ivec2",
3143         Some("make_ivec2"),
3144         Type::new(IVec2),
3145         vec![Type::new(UInt), Type::new(UInt)],
3146     );
3147     declare_function(
3148         state,
3149         "ivec2",
3150         Some("make_ivec2"),
3151         Type::new(IVec2),
3152         vec![Type::new(Int), Type::new(Int)],
3153     );
3154     declare_function(
3155         state,
3156         "ivec2",
3157         Some("make_ivec2"),
3158         Type::new(IVec2),
3159         vec![Type::new(Vec2)],
3160     );
3161     declare_function(
3162         state,
3163         "ivec3",
3164         Some("make_ivec3"),
3165         Type::new(IVec3),
3166         vec![Type::new(IVec2), Type::new(Int)],
3167     );
3168     declare_function(
3169         state,
3170         "ivec4",
3171         Some("make_ivec4"),
3172         Type::new(IVec4),
3173         vec![
3174             Type::new(Int),
3175             Type::new(Int),
3176             Type::new(Int),
3177             Type::new(Int),
3178         ],
3179     );
3180     declare_function(
3181         state,
3182         "ivec4",
3183         Some("make_ivec4"),
3184         Type::new(IVec4),
3185         vec![Type::new(Vec4)],
3186     );
3187     declare_function(
3188         state,
3189         "ivec4",
3190         Some("make_ivec4"),
3191         Type::new(IVec4),
3192         vec![Type::new(IVec2), Type::new(Int), Type::new(Int)],
3193     );
3194 
3195     declare_function(
3196         state,
3197         "mat2",
3198         Some("make_mat2"),
3199         Type::new(Mat2),
3200         vec![Type::new(Vec2), Type::new(Vec2)],
3201     );
3202     declare_function(
3203         state,
3204         "mat2",
3205         Some("make_mat2"),
3206         Type::new(Mat2),
3207         vec![Type::new(Float)],
3208     );
3209     declare_function(
3210         state,
3211         "mat2",
3212         Some("make_mat2"),
3213         Type::new(Mat2),
3214         vec![Type::new(Mat4)],
3215     );
3216     declare_function(
3217         state,
3218         "mat3",
3219         Some("make_mat3"),
3220         Type::new(Mat3),
3221         vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3222     );
3223     declare_function(
3224         state,
3225         "mat3",
3226         Some("make_mat3"),
3227         Type::new(Mat3),
3228         vec![Type::new(Mat4)],
3229     );
3230     declare_function(
3231         state,
3232         "mat3",
3233         Some("make_mat3"),
3234         Type::new(Mat3),
3235         vec![
3236             Type::new(Float),
3237             Type::new(Float),
3238             Type::new(Float),
3239             Type::new(Float),
3240             Type::new(Float),
3241             Type::new(Float),
3242             Type::new(Float),
3243             Type::new(Float),
3244             Type::new(Float),
3245         ],
3246     );
3247     declare_function(
3248         state,
3249         "mat3x4",
3250         Some("make_mat3x4"),
3251         Type::new(Mat34),
3252         vec![
3253             Type::new(Float),
3254             Type::new(Float),
3255             Type::new(Float),
3256             Type::new(Float),
3257 
3258             Type::new(Float),
3259             Type::new(Float),
3260             Type::new(Float),
3261             Type::new(Float),
3262 
3263             Type::new(Float),
3264             Type::new(Float),
3265             Type::new(Float),
3266             Type::new(Float),
3267         ],
3268     );
3269     declare_function(
3270         state,
3271         "transpose",
3272         None,
3273         Type::new(Mat43),
3274         vec![Type::new(Mat34)],
3275     );
3276     declare_function(
3277         state,
3278         "mat4",
3279         Some("make_mat4"),
3280         Type::new(Mat4),
3281         vec![
3282             Type::new(Vec4),
3283             Type::new(Vec4),
3284             Type::new(Vec4),
3285             Type::new(Vec4),
3286         ],
3287     );
3288     declare_function(
3289         state,
3290         "mat4",
3291         Some("make_mat4"),
3292         Type::new(Mat4),
3293         vec![
3294             Type::new(Float),
3295             Type::new(Float),
3296             Type::new(Float),
3297             Type::new(Float),
3298             Type::new(Float),
3299             Type::new(Float),
3300             Type::new(Float),
3301             Type::new(Float),
3302             Type::new(Float),
3303             Type::new(Float),
3304             Type::new(Float),
3305             Type::new(Float),
3306             Type::new(Float),
3307             Type::new(Float),
3308             Type::new(Float),
3309             Type::new(Float),
3310         ],
3311     );
3312     declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3313     declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3314     declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]);
3315     declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3316     declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3317     declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]);
3318     declare_function(
3319         state,
3320         "dot",
3321         None,
3322         Type::new(Float),
3323         vec![Type::new(Vec3), Type::new(Vec3)],
3324     );
3325     declare_function(
3326         state,
3327         "dot",
3328         None,
3329         Type::new(Float),
3330         vec![Type::new(Vec2), Type::new(Vec2)],
3331     );
3332     for t in &[Vec2, Vec3, Vec4] {
3333         declare_function(
3334             state,
3335             "min",
3336             None,
3337             Type::new(*t),
3338             vec![Type::new(*t), Type::new(Float)],
3339         );
3340         declare_function(
3341             state,
3342             "max",
3343             None,
3344             Type::new(*t),
3345             vec![Type::new(*t), Type::new(Float)],
3346         );
3347     }
3348     for t in &[Int, Float, Vec2, Vec3, Vec4] {
3349         declare_function(
3350             state,
3351             "min",
3352             None,
3353             Type::new(*t),
3354             vec![Type::new(*t), Type::new(*t)],
3355         );
3356         declare_function(
3357             state,
3358             "max",
3359             None,
3360             Type::new(*t),
3361             vec![Type::new(*t), Type::new(*t)],
3362         );
3363     }
3364 
3365     declare_function(
3366         state,
3367         "mix",
3368         None,
3369         Type::new(Vec2),
3370         vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3371     );
3372     declare_function(
3373         state,
3374         "mix",
3375         None,
3376         Type::new(Vec2),
3377         vec![Type::new(Vec2), Type::new(Vec2), Type::new(BVec2)],
3378     );
3379     declare_function(
3380         state,
3381         "mix",
3382         None,
3383         Type::new(Vec2),
3384         vec![Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
3385     );
3386     declare_function(
3387         state,
3388         "mix",
3389         None,
3390         Type::new(Vec3),
3391         vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3392     );
3393     declare_function(
3394         state,
3395         "mix",
3396         None,
3397         Type::new(Vec4),
3398         vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
3399     );
3400     declare_function(
3401         state,
3402         "mix",
3403         None,
3404         Type::new(Vec4),
3405         vec![Type::new(Vec4), Type::new(Vec4), Type::new(Float)],
3406     );
3407     declare_function(
3408         state,
3409         "mix",
3410         None,
3411         Type::new(Vec3),
3412         vec![Type::new(Vec3), Type::new(Vec3), Type::new(Float)],
3413     );
3414     declare_function(
3415         state,
3416         "mix",
3417         None,
3418         Type::new(Vec3),
3419         vec![Type::new(Vec3), Type::new(Vec3), Type::new(BVec3)],
3420     );
3421     declare_function(
3422         state,
3423         "mix",
3424         None,
3425         Type::new(Float),
3426         vec![Type::new(Float), Type::new(Float), Type::new(Float)],
3427     );
3428     declare_function(
3429         state,
3430         "mix",
3431         None,
3432         Type::new(Vec4),
3433         vec![Type::new(Vec4), Type::new(Vec4), Type::new(BVec4)],
3434     );
3435     declare_function(
3436         state,
3437         "step",
3438         None,
3439         Type::new(Float),
3440         vec![Type::new(Float), Type::new(Float)],
3441     );
3442     declare_function(
3443         state,
3444         "step",
3445         None,
3446         Type::new(Vec2),
3447         vec![Type::new(Vec2), Type::new(Vec2)],
3448     );
3449     declare_function(
3450         state,
3451         "step",
3452         None,
3453         Type::new(Vec2),
3454         vec![Type::new(Float), Type::new(Vec2)],
3455     );
3456     declare_function(
3457         state,
3458         "step",
3459         None,
3460         Type::new(Vec3),
3461         vec![Type::new(Vec3), Type::new(Vec3)],
3462     );
3463     declare_function(
3464         state,
3465         "step",
3466         None,
3467         Type::new(Vec4),
3468         vec![Type::new(Float), Type::new(Vec4)],
3469     );
3470     declare_function(
3471         state,
3472         "notEqual",
3473         None,
3474         Type::new(BVec4),
3475         vec![Type::new(IVec4), Type::new(IVec4)],
3476     );
3477 
3478     declare_function_ext(
3479         state,
3480         "fwidth",
3481         None,
3482         Type::new(Vec2),
3483         vec![Type::new(Vec2)],
3484         RunClass::Scalar,
3485     );
3486     declare_function_ext(
3487         state,
3488         "dFdx",
3489         None,
3490         Type::new(Float),
3491         vec![Type::new(Float)],
3492         RunClass::Scalar,
3493     );
3494     declare_function_ext(
3495         state,
3496         "dFdx",
3497         None,
3498         Type::new(Vec2),
3499         vec![Type::new(Vec2)],
3500         RunClass::Scalar,
3501     );
3502 
3503     declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
3504     declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
3505     declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
3506     declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
3507     declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
3508     for t in &[Vec2, Vec3, Vec4] {
3509         declare_function(
3510             state,
3511             "clamp",
3512             None,
3513             Type::new(*t),
3514             vec![Type::new(*t), Type::new(Float), Type::new(Float)],
3515         );
3516     }
3517     for t in &[Float, Vec2, Vec3, Vec4] {
3518         declare_function(
3519             state,
3520             "clamp",
3521             None,
3522             Type::new(*t),
3523             vec![Type::new(*t), Type::new(*t), Type::new(*t)],
3524         );
3525     }
3526     declare_function(
3527         state,
3528         "length",
3529         None,
3530         Type::new(Float),
3531         vec![Type::new(Vec2)],
3532     );
3533     declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3534     declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
3535     declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
3536     declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]);
3537     declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]);
3538     declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]);
3539     for t in &[Float, Vec2] {
3540         // recip is non-standard
3541         declare_function(
3542             state,
3543             "recip",
3544             None,
3545             Type::new(*t),
3546             vec![Type::new(*t)],
3547         );
3548         declare_function(
3549             state,
3550             "inversesqrt",
3551             None,
3552             Type::new(*t),
3553             vec![Type::new(*t)],
3554         );
3555         declare_function(
3556             state,
3557             "sqrt",
3558             None,
3559             Type::new(*t),
3560             vec![Type::new(*t)],
3561         );
3562     }
3563     declare_function(
3564         state,
3565         "distance",
3566         None,
3567         Type::new(Float),
3568         vec![Type::new(Vec2), Type::new(Vec2)],
3569     );
3570 
3571     declare_function(
3572         state,
3573         "equal",
3574         None,
3575         Type::new(BVec2),
3576         vec![Type::new(Vec2), Type::new(Vec2)],
3577     );
3578     declare_function(
3579         state,
3580         "equal",
3581         None,
3582         Type::new(BVec4),
3583         vec![Type::new(Vec4), Type::new(Vec4)],
3584     );
3585     declare_function(
3586         state,
3587         "notEqual",
3588         None,
3589         Type::new(BVec2),
3590         vec![Type::new(Vec2), Type::new(Vec2)],
3591     );
3592     declare_function(
3593         state,
3594         "notEqual",
3595         None,
3596         Type::new(BVec4),
3597         vec![Type::new(Vec4), Type::new(Vec4)],
3598     );
3599     declare_function(
3600         state,
3601         "lessThanEqual",
3602         None,
3603         Type::new(BVec2),
3604         vec![Type::new(Vec2), Type::new(Vec2)],
3605     );
3606     declare_function(
3607         state,
3608         "lessThanEqual",
3609         None,
3610         Type::new(BVec3),
3611         vec![Type::new(Vec3), Type::new(Vec3)],
3612     );
3613     declare_function(
3614         state,
3615         "lessThanEqual",
3616         None,
3617         Type::new(BVec4),
3618         vec![Type::new(Vec4), Type::new(Vec4)],
3619     );
3620     declare_function(
3621         state,
3622         "lessThan",
3623         None,
3624         Type::new(BVec2),
3625         vec![Type::new(Vec2), Type::new(Vec2)],
3626     );
3627     declare_function(
3628         state,
3629         "lessThan",
3630         None,
3631         Type::new(BVec4),
3632         vec![Type::new(Vec4), Type::new(Vec4)],
3633     );
3634     declare_function(
3635         state,
3636         "greaterThan",
3637         None,
3638         Type::new(BVec2),
3639         vec![Type::new(Vec2), Type::new(Vec2)],
3640     );
3641     declare_function(
3642         state,
3643         "greaterThan",
3644         None,
3645         Type::new(BVec4),
3646         vec![Type::new(Vec4), Type::new(Vec4)],
3647     );
3648     declare_function(
3649         state,
3650         "greaterThanEqual",
3651         None,
3652         Type::new(BVec2),
3653         vec![Type::new(Vec2), Type::new(Vec2)],
3654     );
3655     declare_function(
3656         state,
3657         "greaterThanEqual",
3658         None,
3659         Type::new(BVec4),
3660         vec![Type::new(Vec4), Type::new(Vec4)],
3661     );
3662     declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]);
3663     declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec2)]);
3664     declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec4)]);
3665 
3666     declare_function(
3667         state,
3668         "if_then_else",
3669         None,
3670         Type::new(Vec3),
3671         vec![Type::new(BVec3), Type::new(Vec3), Type::new(Vec3)],
3672     );
3673     declare_function(state, "floor", None, Type::new(Vec4), vec![Type::new(Vec4)]);
3674     declare_function(state, "floor", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3675     declare_function(
3676         state,
3677         "floor",
3678         None,
3679         Type::new(Float),
3680         vec![Type::new(Float)],
3681     );
3682     declare_function(
3683         state,
3684         "ceil",
3685         None,
3686         Type::new(Float),
3687         vec![Type::new(Float)],
3688     );
3689     declare_function(
3690         state,
3691         "round",
3692         None,
3693         Type::new(Float),
3694         vec![Type::new(Float)],
3695     );
3696     declare_function(
3697         state,
3698         "fract",
3699         None,
3700         Type::new(Float),
3701         vec![Type::new(Float)],
3702     );
3703     declare_function(
3704         state,
3705         "fract",
3706         None,
3707         Type::new(Vec2),
3708         vec![Type::new(Vec2)],
3709     );
3710     declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3711     declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);
3712 
3713     declare_function(
3714         state,
3715         "texelFetch",
3716         None,
3717         Type::new(Vec4),
3718         vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3719     );
3720     declare_function(
3721         state,
3722         "texelFetch",
3723         None,
3724         Type::new(IVec4),
3725         vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)],
3726     );
3727     declare_function(
3728         state,
3729         "texelFetchOffset",
3730         None,
3731         Type::new(Vec4),
3732         vec![
3733             Type::new(Sampler2D),
3734             Type::new(IVec2),
3735             Type::new(Int),
3736             Type::new(IVec2),
3737         ],
3738     );
3739     declare_function(
3740         state,
3741         "texelFetchOffset",
3742         None,
3743         Type::new(IVec4),
3744         vec![
3745             Type::new(ISampler2D),
3746             Type::new(IVec2),
3747             Type::new(Int),
3748             Type::new(IVec2),
3749         ],
3750     );
3751     declare_function(
3752         state,
3753         "texture",
3754         None,
3755         Type::new(Vec4),
3756         vec![Type::new(Sampler2D), Type::new(Vec2)],
3757     );
3758     declare_function(
3759         state,
3760         "texture",
3761         None,
3762         Type::new(Vec4),
3763         vec![Type::new(Sampler2DRect), Type::new(Vec2)],
3764     );
3765     declare_function(
3766         state,
3767         "textureSize",
3768         None,
3769         Type::new(IVec2),
3770         vec![Type::new(Sampler2D), Type::new(Int)],
3771     );
3772     declare_function(
3773         state,
3774         "textureSize",
3775         None,
3776         Type::new(IVec2),
3777         vec![Type::new(Sampler2DRect), Type::new(Int)],
3778     );
3779 
3780     declare_function(
3781         state,
3782         "inverse",
3783         None,
3784         Type::new(Mat2),
3785         vec![Type::new(Mat2)],
3786     );
3787     declare_function(
3788         state,
3789         "transpose",
3790         None,
3791         Type::new(Mat3),
3792         vec![Type::new(Mat3)],
3793     );
3794     declare_function(
3795         state,
3796         "normalize",
3797         None,
3798         Type::new(Vec2),
3799         vec![Type::new(Vec2)],
3800     );
3801     state.declare(
3802         "gl_FragCoord",
3803         SymDecl::Global(StorageClass::In, None, Type::new(Vec4), RunClass::Vector),
3804     );
3805     state.declare(
3806         "gl_FragColor",
3807         SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3808     );
3809     state.declare(
3810         "gl_Position",
3811         SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3812     );
3813     state.clip_dist_sym = state.declare(
3814         "gl_ClipDistance",
3815         SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector),
3816     );
3817 
3818     state.declare(
3819         "swgl_SpanLength",
3820         SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar),
3821     );
3822     state.declare(
3823         "swgl_StepSize",
3824         SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar),
3825     );
3826 
3827     for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] {
3828         declare_function_ext(
3829             state,
3830             "swgl_forceScalar",
3831             None,
3832             Type::new(*t),
3833             vec![Type::new(*t)],
3834             RunClass::Scalar,
3835         );
3836     }
3837 
3838     // GL_ARB_shader_group_vote
3839     for (name, cxx_name) in &[("anyInvocations", "test_any"),
3840                               ("allInvocations", "test_all"),
3841                               ("allInvocationsEqual", "test_equal")] {
3842         declare_function_ext(
3843             state,
3844             name,
3845             Some(cxx_name),
3846             Type::new(Bool),
3847             vec![Type::new(Bool)],
3848             RunClass::Scalar,
3849         );
3850     }
3851 
3852     declare_function(
3853         state,
3854         "swgl_stepInterp",
3855         None,
3856         Type::new(Void),
3857         vec![],
3858     );
3859 
3860     for t in &[Float, Vec2, Vec3, Vec4] {
3861         declare_function_ext(
3862             state,
3863             "swgl_interpStep",
3864             None,
3865             Type::new(*t),
3866             vec![Type::new(*t)],
3867             RunClass::Scalar,
3868         );
3869     }
3870 
3871     declare_function(
3872         state,
3873         "swgl_commitPartialSolidRGBA8",
3874         None,
3875         Type::new(Void),
3876         vec![Type::new(Int), Type::new(Vec4)],
3877     );
3878     declare_function(
3879         state,
3880         "swgl_commitPartialSolidR8",
3881         None,
3882         Type::new(Void),
3883         vec![Type::new(Int), Type::new(Float)],
3884     );
3885     declare_function(
3886         state,
3887         "swgl_commitSolidRGBA8",
3888         None,
3889         Type::new(Void),
3890         vec![Type::new(Vec4)],
3891     );
3892     declare_function(
3893         state,
3894         "swgl_commitSolidR8",
3895         None,
3896         Type::new(Void),
3897         vec![Type::new(Float)],
3898     );
3899     declare_function(
3900         state,
3901         "swgl_commitColorRGBA8",
3902         None,
3903         Type::new(Void),
3904         vec![Type::new(Vec4)],
3905     );
3906     declare_function(
3907         state,
3908         "swgl_commitColorR8",
3909         None,
3910         Type::new(Void),
3911         vec![Type::new(Float)],
3912     );
3913     declare_function(
3914         state,
3915         "swgl_blendDropShadow",
3916         None,
3917         Type::new(Void),
3918         vec![Type::new(Vec4)],
3919     );
3920     declare_function(
3921         state,
3922         "swgl_blendSubpixelText",
3923         None,
3924         Type::new(Void),
3925         vec![Type::new(Vec4)],
3926     );
3927     declare_function(
3928         state,
3929         "swgl_clipMask",
3930         None,
3931         Type::new(Void),
3932         vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3933     );
3934     declare_function(
3935         state,
3936         "swgl_antiAlias",
3937         None,
3938         Type::new(Void),
3939         vec![Type::new(Int)],
3940     );
3941     declare_function(
3942         state,
3943         "swgl_antiAlias",
3944         None,
3945         Type::new(Void),
3946         vec![Type::new(BVec4)],
3947     );
3948     declare_function_ext(
3949         state,
3950         "swgl_validateGradient",
3951         None,
3952         Type::new(Int),
3953         vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3954         RunClass::Scalar,
3955     );
3956     declare_function(
3957         state,
3958         "swgl_commitLinearGradientRGBA8",
3959         None,
3960         Type::new(Void),
3961         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Float)],
3962     );
3963     declare_function(
3964         state,
3965         "swgl_commitRadialGradientRGBA8",
3966         None,
3967         Type::new(Void),
3968         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
3969              Type::new(Float)],
3970     );
3971     declare_function(
3972         state,
3973         "swgl_commitGradientRGBA8",
3974         None,
3975         Type::new(Void),
3976         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)],
3977     );
3978     declare_function(
3979         state,
3980         "swgl_commitGradientColorRGBA8",
3981         None,
3982         Type::new(Void),
3983         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)],
3984     );
3985     for s in &[Sampler2D, Sampler2DRect] {
3986         declare_function_ext(
3987             state,
3988             "swgl_isTextureLinear",
3989             None,
3990             Type::new(Bool),
3991             vec![Type::new(*s)],
3992             RunClass::Scalar,
3993         );
3994         declare_function_ext(
3995             state,
3996             "swgl_isTextureRGBA8",
3997             None,
3998             Type::new(Bool),
3999             vec![Type::new(*s)],
4000             RunClass::Scalar,
4001         );
4002         declare_function_ext(
4003             state,
4004             "swgl_isTextureR8",
4005             None,
4006             Type::new(Bool),
4007             vec![Type::new(*s)],
4008             RunClass::Scalar,
4009         );
4010         declare_function(
4011             state,
4012             "swgl_commitTextureLinearRGBA8",
4013             None,
4014             Type::new(Void),
4015             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4016         );
4017         declare_function(
4018             state,
4019             "swgl_commitTextureLinearR8",
4020             None,
4021             Type::new(Void),
4022             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4023         );
4024         declare_function(
4025             state,
4026             "swgl_commitTextureLinearR8ToRGBA8",
4027             None,
4028             Type::new(Void),
4029             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4030         );
4031         declare_function(
4032             state,
4033             "swgl_commitPartialTextureLinearR8",
4034             None,
4035             Type::new(Void),
4036             vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4037         );
4038         declare_function(
4039             state,
4040             "swgl_commitPartialTextureLinearInvertR8",
4041             None,
4042             Type::new(Void),
4043             vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4044         );
4045         declare_function(
4046             state,
4047             "swgl_commitTextureLinearColorRGBA8",
4048             None,
4049             Type::new(Void),
4050             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4051         );
4052         declare_function(
4053             state,
4054             "swgl_commitTextureLinearColorRGBA8",
4055             None,
4056             Type::new(Void),
4057             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4058         );
4059         declare_function(
4060             state,
4061             "swgl_commitTextureLinearColorR8",
4062             None,
4063             Type::new(Void),
4064             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4065         );
4066         declare_function(
4067             state,
4068             "swgl_commitTextureLinearColorR8ToRGBA8",
4069             None,
4070             Type::new(Void),
4071             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4072         );
4073 
4074         declare_function(
4075             state,
4076             "swgl_commitTextureLinearRepeatRGBA8",
4077             None,
4078             Type::new(Void),
4079             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4080                  Type::new(Vec4), Type::new(Vec4)],
4081         );
4082         declare_function(
4083             state,
4084             "swgl_commitTextureLinearRepeatColorRGBA8",
4085             None,
4086             Type::new(Void),
4087             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4088                  Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4089         );
4090 
4091         declare_function(
4092             state,
4093             "swgl_commitTextureNearestRGBA8",
4094             None,
4095             Type::new(Void),
4096             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4097         );
4098         declare_function(
4099             state,
4100             "swgl_commitTextureNearestColorRGBA8",
4101             None,
4102             Type::new(Void),
4103             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4104         );
4105         declare_function(
4106             state,
4107             "swgl_commitTextureNearestRepeatRGBA8",
4108             None,
4109             Type::new(Void),
4110             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4111                  Type::new(Vec4), Type::new(Vec4)],
4112         );
4113         declare_function(
4114             state,
4115             "swgl_commitTextureNearestRepeatColorRGBA8",
4116             None,
4117             Type::new(Void),
4118             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4119                  Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4120         );
4121 
4122         declare_function(
4123             state,
4124             "swgl_commitTextureRGBA8",
4125             None,
4126             Type::new(Void),
4127             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4128         );
4129         declare_function(
4130             state,
4131             "swgl_commitTextureColorRGBA8",
4132             None,
4133             Type::new(Void),
4134             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4135         );
4136         declare_function(
4137             state,
4138             "swgl_commitTextureRepeatRGBA8",
4139             None,
4140             Type::new(Void),
4141             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4142                  Type::new(Vec4), Type::new(Vec4)],
4143         );
4144         declare_function(
4145             state,
4146             "swgl_commitTextureRepeatColorRGBA8",
4147             None,
4148             Type::new(Void),
4149             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4150                  Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4151         );
4152 
4153         declare_function(
4154             state,
4155             "swgl_commitGaussianBlurRGBA8",
4156             None,
4157             Type::new(Void),
4158             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4159                  Type::new(Int), Type::new(Vec2)],
4160         );
4161         declare_function(
4162             state,
4163             "swgl_commitGaussianBlurR8",
4164             None,
4165             Type::new(Void),
4166             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4167                  Type::new(Int), Type::new(Vec2)],
4168         );
4169         declare_function(
4170             state,
4171             "swgl_commitTextureLinearYUV",
4172             None,
4173             Type::new(Void),
4174             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4175                  Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4176         );
4177         declare_function(
4178             state,
4179             "swgl_commitTextureLinearYUV",
4180             None,
4181             Type::new(Void),
4182             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4183                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4184                  Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4185         );
4186         declare_function(
4187             state,
4188             "swgl_commitTextureLinearYUV",
4189             None,
4190             Type::new(Void),
4191             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4192                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4193                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4194                  Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4195         );
4196         declare_function(
4197             state,
4198             "swgl_commitTextureLinearColorYUV",
4199             None,
4200             Type::new(Void),
4201             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4202                  Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4203                  Type::new(Float)],
4204         );
4205         declare_function(
4206             state,
4207             "swgl_commitTextureLinearColorYUV",
4208             None,
4209             Type::new(Void),
4210             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4211                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4212                  Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4213                  Type::new(Float)],
4214         );
4215         declare_function(
4216             state,
4217             "swgl_commitTextureLinearColorYUV",
4218             None,
4219             Type::new(Void),
4220             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4221                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4222                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4223                  Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4224                  Type::new(Float)],
4225         );
4226     }
4227 
4228     TranslationUnit(tu.0.map(state, translate_external_declaration))
4229 }
4230 
infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass4231 fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass {
4232     match expr.kind {
4233         ExprKind::Variable(ref i) => {
4234             *assign = *i;
4235             match &state.sym(*i).decl {
4236                 SymDecl::Local(_, _, ref run_class) => *run_class,
4237                 SymDecl::Global(_, _, _, ref run_class) => *run_class,
4238                 _ => panic!(),
4239             }
4240         }
4241         ExprKind::IntConst(_)
4242         | ExprKind::UIntConst(_)
4243         | ExprKind::BoolConst(_)
4244         | ExprKind::FloatConst(_)
4245         | ExprKind::DoubleConst(_) => RunClass::Scalar,
4246         ExprKind::Unary(_, ref e) => infer_expr(state, e),
4247         ExprKind::Binary(_, ref l, ref r) => infer_expr(state, l).merge(infer_expr(state, r)),
4248         ExprKind::Ternary(ref c, ref s, ref e) => infer_expr(state, c)
4249             .merge(infer_expr(state, s))
4250             .merge(infer_expr(state, e)),
4251         ExprKind::Assignment(ref v, _, ref e) => {
4252             let mut sym = SymRef(!0);
4253             let run_class = infer_expr_inner(state, v, &mut sym).merge(infer_expr(state, e));
4254             assert!(sym != SymRef(!0));
4255             state.merge_run_class(sym, run_class)
4256         }
4257         ExprKind::Bracket(ref e, ref indx) => {
4258             infer_expr_inner(state, e, assign).merge(infer_expr(state, indx))
4259         }
4260         ExprKind::FunCall(ref fun, ref args) => {
4261             let arg_classes: Vec<(RunClass, SymRef)> = args
4262                 .iter()
4263                 .map(|e| {
4264                     let mut assign = SymRef(!0);
4265                     let run_class = infer_expr_inner(state, e, &mut assign);
4266                     (run_class, assign)
4267                 })
4268                 .collect();
4269             let run_class = if args.is_empty() {
4270                 RunClass::Scalar
4271             } else {
4272                 arg_classes
4273                     .iter()
4274                     .fold(RunClass::Unknown, |x, &(y, _)| x.merge(y))
4275             };
4276             match fun {
4277                 FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl {
4278                     SymDecl::NativeFunction(_, _, ref ret_class) => {
4279                         if *ret_class != RunClass::Unknown {
4280                             *ret_class
4281                         } else {
4282                             run_class
4283                         }
4284                     }
4285                     SymDecl::UserFunction(ref fd, ref run_class) => {
4286                         for (&(mut arg_class, assign), param) in
4287                             arg_classes.iter().zip(fd.prototype.parameters.iter())
4288                         {
4289                             if let FunctionParameterDeclaration::Named(Some(qual), p) = param {
4290                                 match qual {
4291                                     ParameterQualifier::InOut | ParameterQualifier::Out => {
4292                                         if let SymDecl::Local(_, _, param_class) =
4293                                             &state.sym(p.sym).decl
4294                                         {
4295                                             match param_class {
4296                                                 RunClass::Unknown | RunClass::Vector => {
4297                                                     arg_class = RunClass::Vector;
4298                                                 }
4299                                                 RunClass::Dependent(mask) => {
4300                                                     for i in 0 .. 31 {
4301                                                         if (mask & (1 << i)) != 0 {
4302                                                             arg_class =
4303                                                                 arg_class.merge(arg_classes[i].0);
4304                                                         }
4305                                                     }
4306                                                 }
4307                                                 RunClass::Scalar => {}
4308                                             }
4309                                         }
4310                                         assert!(assign != SymRef(!0));
4311                                         state.merge_run_class(assign, arg_class);
4312                                     }
4313                                     _ => {}
4314                                 }
4315                             }
4316                         }
4317                         if fd.prototype.ty.kind == TypeKind::Void {
4318                             RunClass::Scalar
4319                         } else {
4320                             match *run_class {
4321                                 RunClass::Unknown | RunClass::Vector => RunClass::Vector,
4322                                 RunClass::Dependent(mask) => {
4323                                     let mut ret_class = RunClass::Unknown;
4324                                     for i in 0 .. 31 {
4325                                         if (mask & (1 << i)) != 0 {
4326                                             ret_class = ret_class.merge(arg_classes[i].0);
4327                                         }
4328                                     }
4329                                     ret_class
4330                                 }
4331                                 RunClass::Scalar => RunClass::Scalar,
4332                             }
4333                         }
4334                     }
4335                     SymDecl::Struct(..) => run_class,
4336                     _ => panic!(),
4337                 },
4338                 FunIdentifier::Constructor(..) => run_class,
4339             }
4340         }
4341         ExprKind::Dot(ref e, _) => infer_expr_inner(state, e, assign),
4342         ExprKind::SwizzleSelector(ref e, _) => infer_expr_inner(state, e, assign),
4343         ExprKind::PostInc(ref e) => infer_expr_inner(state, e, assign),
4344         ExprKind::PostDec(ref e) => infer_expr_inner(state, e, assign),
4345         ExprKind::Comma(ref a, ref b) => {
4346             infer_expr(state, a);
4347             infer_expr(state, b)
4348         }
4349         ExprKind::Cond(_, ref e) => infer_expr(state, e),
4350         ExprKind::CondMask => RunClass::Vector,
4351     }
4352 }
4353 
infer_expr(state: &mut State, expr: &Expr) -> RunClass4354 fn infer_expr(state: &mut State, expr: &Expr) -> RunClass {
4355     infer_expr_inner(state, expr, &mut SymRef(!0))
4356 }
4357 
infer_condition(state: &mut State, c: &Condition)4358 fn infer_condition(state: &mut State, c: &Condition) {
4359     match *c {
4360         Condition::Expr(ref e) => {
4361             infer_expr(state, e);
4362         }
4363     }
4364 }
4365 
infer_iteration_statement(state: &mut State, ist: &IterationStatement)4366 fn infer_iteration_statement(state: &mut State, ist: &IterationStatement) {
4367     let changed = state.run_class_changed.replace(true);
4368     match *ist {
4369         IterationStatement::While(ref cond, ref body) => {
4370             while state.run_class_changed.replace(false) {
4371                 infer_condition(state, cond);
4372                 infer_statement(state, body);
4373             }
4374         }
4375         IterationStatement::DoWhile(ref body, ref cond) => {
4376             while state.run_class_changed.replace(false) {
4377                 infer_statement(state, body);
4378                 infer_expr(state, cond);
4379             }
4380         }
4381         IterationStatement::For(ref init, ref rest, ref body) => {
4382             match *init {
4383                 ForInitStatement::Expression(ref expr) => {
4384                     if let Some(ref e) = *expr {
4385                         infer_expr(state, e);
4386                     }
4387                 }
4388                 ForInitStatement::Declaration(ref d) => {
4389                     infer_declaration(state, d);
4390                 }
4391             }
4392             while state.run_class_changed.replace(false) {
4393                 if let Some(ref cond) = rest.condition {
4394                     infer_condition(state, cond);
4395                 }
4396                 if let Some(ref e) = rest.post_expr {
4397                     infer_expr(state, e);
4398                 }
4399                 infer_statement(state, body);
4400             }
4401         }
4402     }
4403     state.run_class_changed.set(changed);
4404 }
4405 
infer_selection_statement(state: &mut State, sst: &SelectionStatement)4406 fn infer_selection_statement(state: &mut State, sst: &SelectionStatement) {
4407     let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.cond));
4408     mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4409     let branch_declaration = state.branch_declaration;
4410     state.branch_declaration = state.last_declaration;
4411     infer_statement(state, &sst.body);
4412     if let Some(ref else_st) = sst.else_stmt {
4413         infer_statement(state, else_st);
4414     }
4415     state.branch_run_class = branch_run_class;
4416     state.branch_declaration = branch_declaration;
4417 }
4418 
infer_expression_statement(state: &mut State, est: &ExprStatement)4419 fn infer_expression_statement(state: &mut State, est: &ExprStatement) {
4420     if let Some(ref e) = *est {
4421         infer_expr(state, e);
4422     }
4423 }
4424 
infer_switch_statement(state: &mut State, sst: &SwitchStatement)4425 fn infer_switch_statement(state: &mut State, sst: &SwitchStatement) {
4426     let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.head));
4427     mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4428     let branch_declaration = state.branch_declaration;
4429     state.branch_declaration = state.last_declaration;
4430     for case in &sst.cases {
4431         for st in &case.stmts {
4432             infer_statement(state, st);
4433         }
4434     }
4435     state.branch_run_class = branch_run_class;
4436     state.branch_declaration = branch_declaration;
4437 }
4438 
infer_jump_statement(state: &mut State, j: &JumpStatement)4439 fn infer_jump_statement(state: &mut State, j: &JumpStatement) {
4440     match *j {
4441         JumpStatement::Continue => {}
4442         JumpStatement::Break => {}
4443         JumpStatement::Discard => {}
4444         JumpStatement::Return(ref e) => {
4445             if let Some(e) = e {
4446                 let run_class = infer_expr(state, e);
4447                 state.return_run_class(run_class);
4448             }
4449         }
4450     }
4451 }
4452 
infer_initializer(state: &mut State, i: &Initializer) -> RunClass4453 fn infer_initializer(state: &mut State, i: &Initializer) -> RunClass {
4454     match *i {
4455         Initializer::Simple(ref e) => infer_expr(state, e),
4456         Initializer::List(ref list) => {
4457             let mut run_class = RunClass::Unknown;
4458             for ini in list.0.iter() {
4459                 run_class = run_class.merge(infer_initializer(state, ini));
4460             }
4461             run_class
4462         }
4463     }
4464 }
4465 
infer_declaration(state: &mut State, d: &Declaration)4466 fn infer_declaration(state: &mut State, d: &Declaration) {
4467     match *d {
4468         Declaration::FunctionPrototype(..) => {}
4469         Declaration::InitDeclaratorList(ref list) => {
4470             state.last_declaration = list.head.name;
4471 
4472             let mut run_class = RunClass::Unknown;
4473             for decl in &list.tail {
4474                 if let Some(ref initializer) = decl.initializer {
4475                     run_class = run_class.merge(infer_initializer(state, initializer));
4476                 }
4477             }
4478             if let Some(ref initializer) = list.head.initializer {
4479                 run_class = run_class.merge(infer_initializer(state, initializer));
4480                 state.merge_run_class(list.head.name, run_class);
4481             }
4482         }
4483         Declaration::Precision(..) => {}
4484         Declaration::Block(..) => {}
4485         Declaration::Global(..) => {}
4486         Declaration::StructDefinition(..) => {}
4487     }
4488 }
4489 
infer_simple_statement(state: &mut State, sst: &SimpleStatement)4490 fn infer_simple_statement(state: &mut State, sst: &SimpleStatement) {
4491     match *sst {
4492         SimpleStatement::Declaration(ref d) => infer_declaration(state, d),
4493         SimpleStatement::Expression(ref e) => infer_expression_statement(state, e),
4494         SimpleStatement::Selection(ref s) => infer_selection_statement(state, s),
4495         SimpleStatement::Switch(ref s) => infer_switch_statement(state, s),
4496         SimpleStatement::Iteration(ref i) => infer_iteration_statement(state, i),
4497         SimpleStatement::Jump(ref j) => infer_jump_statement(state, j),
4498     }
4499 }
4500 
infer_compound_statement(state: &mut State, cst: &CompoundStatement)4501 fn infer_compound_statement(state: &mut State, cst: &CompoundStatement) {
4502     for st in &cst.statement_list {
4503         infer_statement(state, st);
4504     }
4505 }
4506 
infer_statement(state: &mut State, st: &Statement)4507 fn infer_statement(state: &mut State, st: &Statement) {
4508     match *st {
4509         Statement::Compound(ref cst) => infer_compound_statement(state, cst),
4510         Statement::Simple(ref sst) => infer_simple_statement(state, sst),
4511     }
4512 }
4513 
infer_function_definition(state: &mut State, fd: &FunctionDefinition)4514 fn infer_function_definition(state: &mut State, fd: &FunctionDefinition) {
4515     state.in_function = Some(state.lookup(fd.prototype.name.as_str()).unwrap());
4516 
4517     state.run_class_changed.set(true);
4518     while state.run_class_changed.replace(false) {
4519         for st in &fd.body.statement_list {
4520             infer_statement(state, st);
4521         }
4522     }
4523 
4524     state.in_function = None;
4525 }
4526 
infer_external_declaration(state: &mut State, ed: &ExternalDeclaration)4527 fn infer_external_declaration(state: &mut State, ed: &ExternalDeclaration) {
4528     match *ed {
4529         ExternalDeclaration::Preprocessor(_) => {}
4530         ExternalDeclaration::FunctionDefinition(ref fd) => infer_function_definition(state, fd),
4531         ExternalDeclaration::Declaration(_) => {}
4532     }
4533 }
4534 
infer_run_class(state: &mut State, tu: &TranslationUnit)4535 pub fn infer_run_class(state: &mut State, tu: &TranslationUnit) {
4536     for ed in &(tu.0).0 {
4537         infer_external_declaration(state, ed);
4538     }
4539 }
4540