tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hir.rs (149474B)


      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, ArraySpecifierDimension, 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> {
     49    fn lift(state: &mut State, s: S) -> Self;
     50 }
     51 
     52 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 {
     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 {
    113    fn lift(state: &mut State, a: &ArraySpecifier) -> Self {
    114        ArraySizes {
    115            sizes: a.dimensions.0.iter().map(|a| match a {
    116                ArraySpecifierDimension::Unsized => panic!(),
    117                ArraySpecifierDimension::ExplicitlySized(expr) => translate_expression(state, expr),
    118            }).collect(),
    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 {
    245    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 
    325    pub fn is_bool(&self) -> bool {
    326        use TypeKind::*;
    327        match self {
    328            Bool | BVec2 | BVec3 | BVec4 => true,
    329            _ => false,
    330        }
    331    }
    332 
    333    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 
    344    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 
    355    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 
    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 
    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 
    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 
    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 
    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 {
    760    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 {
    784    pub fn new(kind: TypeKind) -> Self {
    785        Type {
    786            kind,
    787            precision: None,
    788            array_sizes: None,
    789        }
    790    }
    791 
    792    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 {
    802    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 {
    818    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 
    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 {
    855    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 {
    878    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 {
    893    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 {
    928    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 {
    945    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 
    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 {
    979    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 
    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 
   1005    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 
   1015    pub fn sym(&self, sym: SymRef) -> Ref<Symbol> {
   1016        self.syms[sym.0 as usize].borrow()
   1017    }
   1018 
   1019    pub fn sym_mut(&mut self, sym: SymRef) -> &mut Symbol {
   1020        self.syms[sym.0 as usize].get_mut()
   1021    }
   1022 
   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 
   1028    fn push_scope(&mut self, name: String) {
   1029        self.scopes.push(Scope::new(name));
   1030    }
   1031    fn pop_scope(&mut self) {
   1032        self.scopes.pop();
   1033    }
   1034 
   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 
   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 
   1053    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 {
   1108    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 
   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 
   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 {
   1246    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 {
   1271    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 
   1341    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 
   1354    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>, Vec<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.
   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 
   1458    fn deref(&self) -> &Self::Target {
   1459        &self.0
   1460    }
   1461 }
   1462 
   1463 impl DerefMut for TranslationUnit {
   1464    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 
   1473    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 
   1482    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 
   1491    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 {
   1520    pub fn new() -> Self {
   1521        CompoundStatement {
   1522            statement_list: Vec::new(),
   1523        }
   1524    }
   1525 }
   1526 
   1527 impl FromIterator<Statement> for CompoundStatement {
   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.
   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).
   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.
   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.
   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 {
   1623    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> {
   1681    fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>;
   1682    fn new(x: T) -> NonEmpty<T>;
   1683 }
   1684 
   1685 impl<T> NonEmptyExt<T> for NonEmpty<T> {
   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    }
   1689    fn new(x: T) -> NonEmpty<T> {
   1690        NonEmpty::from_non_empty_iter(vec![x].into_iter()).unwrap()
   1691    }
   1692 }
   1693 
   1694 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 
   1703 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 
   1718 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 
   1728 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 
   1892 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 
   1903 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 
   1948 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 
   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 
   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 
   2017 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 
   2024 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 
   2049 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 
   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 
   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 
   2141 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.
   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.
   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 
   2199 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                        for dimension in idx {
   2243                            let idx = match dimension.kind {
   2244                                ExprKind::IntConst(idx) => idx,
   2245                                ExprKind::UIntConst(idx) => idx as i32,
   2246                                _ => panic!("bad index for gl_ClipDistance"),
   2247                            };
   2248                            assert!(idx >= 0 && idx < 4);
   2249                            state.used_clip_dist |= 1 << idx;
   2250                        }
   2251                    }
   2252                }
   2253            }
   2254            Expr {
   2255                kind: ExprKind::Assignment(lhs, op.clone(), rhs),
   2256                ty,
   2257            }
   2258        }
   2259        syntax::Expr::Binary(op, lhs, rhs) => {
   2260            let lhs = Box::new(translate_expression(state, lhs));
   2261            let rhs = Box::new(translate_expression(state, rhs));
   2262            let ty = match op {
   2263                BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
   2264                    // comparison operators have a bool result
   2265                    Type::new(TypeKind::Bool)
   2266                }
   2267                BinaryOp::Mult => {
   2268                    match (lhs.ty.kind, rhs.ty.kind) {
   2269                        (TypeKind::Mat2, TypeKind::Vec2) |
   2270                        (TypeKind::Mat3, TypeKind::Vec3) |
   2271                        (TypeKind::Mat3, TypeKind::Mat3) |
   2272                        (TypeKind::Mat3, TypeKind::Mat43) |
   2273                        (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(),
   2274                        (TypeKind::Mat43, TypeKind::Vec4) => Type::new(TypeKind::Vec3),
   2275                        (TypeKind::Mat2, TypeKind::Float) |
   2276                        (TypeKind::Mat3, TypeKind::Float) |
   2277                        (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(),
   2278                        _ => promoted_type(&lhs.ty, &rhs.ty),
   2279                    }
   2280                }
   2281                _ => promoted_type(&lhs.ty, &rhs.ty),
   2282            };
   2283 
   2284            Expr {
   2285                kind: ExprKind::Binary(op.clone(), lhs, rhs),
   2286                ty,
   2287            }
   2288        }
   2289        syntax::Expr::Unary(op, e) => {
   2290            let e = Box::new(translate_expression(state, e));
   2291            let ty = e.ty.clone();
   2292            Expr {
   2293                kind: ExprKind::Unary(op.clone(), e),
   2294                ty,
   2295            }
   2296        }
   2297        syntax::Expr::BoolConst(b) => Expr {
   2298            kind: ExprKind::BoolConst(*b),
   2299            ty: Type::new(TypeKind::Bool),
   2300        },
   2301        syntax::Expr::Comma(lhs, rhs) => {
   2302            let lhs = Box::new(translate_expression(state, lhs));
   2303            let rhs = Box::new(translate_expression(state, rhs));
   2304            assert_eq!(lhs.ty, rhs.ty);
   2305            let ty = lhs.ty.clone();
   2306            Expr {
   2307                kind: ExprKind::Comma(lhs, rhs),
   2308                ty,
   2309            }
   2310        }
   2311        syntax::Expr::DoubleConst(d) => Expr {
   2312            kind: ExprKind::DoubleConst(*d),
   2313            ty: Type::new(TypeKind::Double),
   2314        },
   2315        syntax::Expr::FloatConst(f) => Expr {
   2316            kind: ExprKind::FloatConst(*f),
   2317            ty: Type::new(TypeKind::Float),
   2318        },
   2319        syntax::Expr::FunCall(fun, params) => {
   2320            let ret_ty: Type;
   2321            let mut params: Vec<Expr> = params
   2322                .iter()
   2323                .map(|x| translate_expression(state, x))
   2324                .collect();
   2325            Expr {
   2326                kind: ExprKind::FunCall(
   2327                    match fun {
   2328                        syntax::FunIdentifier::Identifier(i) => {
   2329                            let name = i.as_str();
   2330                            if name == "texelFetchOffset" && params.len() >= 4 {
   2331                                if let Some((sampler, base, x, y)) = get_texel_fetch_offset(
   2332                                    state, &params[0], &params[1], &params[3],
   2333                                ) {
   2334                                    if let Some(offsets) =
   2335                                        state.texel_fetches.get_mut(&(sampler, base))
   2336                                    {
   2337                                        offsets.add_offset(x, y);
   2338                                    } else {
   2339                                        state
   2340                                            .texel_fetches
   2341                                            .insert((sampler, base), TexelFetchOffsets::new(x, y));
   2342                                    }
   2343                                }
   2344                            } else if name == "swgl_stepInterp" {
   2345                                let mut globals = state.modified_globals.borrow_mut();
   2346                                for (i, sym) in state.syms.iter().enumerate() {
   2347                                    match &sym.borrow().decl {
   2348                                        SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => {
   2349                                            let symref = SymRef(i as u32);
   2350                                            if !globals.contains(&symref) {
   2351                                                globals.push(symref);
   2352                                            }
   2353                                        }
   2354                                        _ => {}
   2355                                    }
   2356                                }
   2357                            }
   2358                            let sym = match state.lookup(name) {
   2359                                Some(s) => s,
   2360                                None => panic!("missing symbol {}", name),
   2361                            };
   2362                            // Force any boolean basic type constructors to generate correct
   2363                            // bit patterns.
   2364                            if let Some(t) = TypeKind::from_glsl_primitive_type_name(name) {
   2365                                if t.is_bool() {
   2366                                    force_params_to_bool(state, &mut params);
   2367                                } else {
   2368                                    force_params_from_bool(state, &mut params);
   2369                                }
   2370                            }
   2371                            match &state.sym(sym).decl {
   2372                                SymDecl::NativeFunction(fn_ty, _, _) => {
   2373                                    // Search for a signature where all parameter types are
   2374                                    // compatible. If there are many compatible signatures,
   2375                                    // then choose the one with the most exact matches.
   2376                                    // This is an approximation of the algorith described in
   2377                                    // the "Function Definitions" section of the spec.
   2378                                    let mut ret = None;
   2379                                    let mut best_score = 0;
   2380                                    'next_sig: for sig in &fn_ty.signatures {
   2381                                        let mut score = 0;
   2382                                        for (e, p) in params.iter().zip(sig.params.iter()) {
   2383                                            if e.ty == *p {
   2384                                                score += 1;
   2385                                            } else if !can_implicitly_convert_to(&e.ty, p) {
   2386                                                continue 'next_sig;
   2387                                            }
   2388                                        }
   2389                                        if score >= best_score {
   2390                                            ret = Some(sig.ret.clone());
   2391                                            best_score = score;
   2392                                            // If all parameters match exactly, then there
   2393                                            // is no need to search for other matches.
   2394                                            if best_score >= params.len() {
   2395                                                break;
   2396                                            }
   2397                                        }
   2398                                    }
   2399                                    ret_ty = match ret {
   2400                                        Some(t) => t,
   2401                                        None => {
   2402                                            dbg!(&fn_ty.signatures);
   2403                                            dbg!(params.iter().map(|p| p).collect::<Vec<_>>());
   2404                                            panic!("no matching func {}", i.as_str())
   2405                                        }
   2406                                    };
   2407                                }
   2408                                SymDecl::UserFunction(fd, _) => {
   2409                                    let mut globals = state.modified_globals.borrow_mut();
   2410                                    for global in &fd.globals {
   2411                                        if !globals.contains(global) {
   2412                                            globals.push(*global);
   2413                                        }
   2414                                    }
   2415                                    let mut matching = true;
   2416                                    for (e, p) in params.iter().zip(fd.prototype.parameters.iter())
   2417                                    {
   2418                                        matching &= match p {
   2419                                            FunctionParameterDeclaration::Named(q, d) => {
   2420                                                match q {
   2421                                                    Some(ParameterQualifier::InOut)
   2422                                                    | Some(ParameterQualifier::Out) => {
   2423                                                        if let Some(global) = is_output(e, state) {
   2424                                                            if !globals.contains(&global) {
   2425                                                                globals.push(global);
   2426                                                            }
   2427                                                        }
   2428                                                    }
   2429                                                    _ => {}
   2430                                                }
   2431                                                can_implicitly_convert_to(&e.ty, &d.ty)
   2432                                            }
   2433                                            FunctionParameterDeclaration::Unnamed(..) => panic!(),
   2434                                        };
   2435                                    }
   2436                                    assert!(matching);
   2437                                    ret_ty = fd.prototype.ty.clone();
   2438                                }
   2439                                SymDecl::Struct(_) => ret_ty = Type::new(TypeKind::Struct(sym)),
   2440                                _ => panic!("can only call functions"),
   2441                            };
   2442                            FunIdentifier::Identifier(sym)
   2443                        }
   2444                        // array constructor
   2445                        syntax::FunIdentifier::Expr(e) => {
   2446                            let ty = match &**e {
   2447                                syntax::Expr::Bracket(i, array) => {
   2448                                    let kind = match &**i {
   2449                                        syntax::Expr::Variable(i) => match i.as_str() {
   2450                                            "vec4" => TypeKind::Vec4,
   2451                                            "vec2" => TypeKind::Vec2,
   2452                                            "int" => TypeKind::Int,
   2453                                            _ => panic!("unexpected type constructor {:?}", i),
   2454                                        },
   2455                                        _ => panic!(),
   2456                                    };
   2457 
   2458                                    Type {
   2459                                        kind,
   2460                                        precision: None,
   2461                                        array_sizes: Some(Box::new(lift(state, array))),
   2462                                    }
   2463                                }
   2464                                _ => panic!(),
   2465                            };
   2466                            ret_ty = ty.clone();
   2467 
   2468                            FunIdentifier::Constructor(ty)
   2469                        }
   2470                    },
   2471                    params,
   2472                ),
   2473                ty: ret_ty,
   2474            }
   2475        }
   2476        syntax::Expr::IntConst(i) => Expr {
   2477            kind: ExprKind::IntConst(*i),
   2478            ty: Type::new(TypeKind::Int),
   2479        },
   2480        syntax::Expr::UIntConst(u) => Expr {
   2481            kind: ExprKind::UIntConst(*u),
   2482            ty: Type::new(TypeKind::UInt),
   2483        },
   2484        syntax::Expr::PostDec(e) => {
   2485            let e = Box::new(translate_expression(state, e));
   2486            let ty = e.ty.clone();
   2487            Expr {
   2488                kind: ExprKind::PostDec(e),
   2489                ty,
   2490            }
   2491        }
   2492        syntax::Expr::PostInc(e) => {
   2493            let e = Box::new(translate_expression(state, e));
   2494            let ty = e.ty.clone();
   2495            Expr {
   2496                kind: ExprKind::PostInc(e),
   2497                ty,
   2498            }
   2499        }
   2500        syntax::Expr::Ternary(cond, lhs, rhs) => {
   2501            let cond = Box::new(translate_expression(state, cond));
   2502            let lhs = Box::new(translate_expression(state, lhs));
   2503            let rhs = Box::new(translate_expression(state, rhs));
   2504            let ty = promoted_type(&lhs.ty, &rhs.ty);
   2505            Expr {
   2506                kind: ExprKind::Ternary(cond, lhs, rhs),
   2507                ty,
   2508            }
   2509        }
   2510        syntax::Expr::Dot(e, i) => {
   2511            let e = Box::new(translate_expression(state, e));
   2512            let ty = e.ty.clone();
   2513            let ivec = is_ivec(&ty);
   2514            if is_vector(&ty) {
   2515                let ty = Type::new(match i.as_str().len() {
   2516                    1 => {
   2517                        if ivec {
   2518                            TypeKind::Int
   2519                        } else {
   2520                            TypeKind::Float
   2521                        }
   2522                    }
   2523                    2 => {
   2524                        if ivec {
   2525                            TypeKind::IVec2
   2526                        } else {
   2527                            TypeKind::Vec2
   2528                        }
   2529                    }
   2530                    3 => {
   2531                        if ivec {
   2532                            TypeKind::IVec3
   2533                        } else {
   2534                            TypeKind::Vec3
   2535                        }
   2536                    }
   2537                    4 => {
   2538                        if ivec {
   2539                            TypeKind::IVec4
   2540                        } else {
   2541                            TypeKind::Vec4
   2542                        }
   2543                    }
   2544                    _ => panic!(),
   2545                });
   2546 
   2547                let sel = SwizzleSelector::parse(i.as_str());
   2548 
   2549                Expr {
   2550                    kind: ExprKind::SwizzleSelector(e, sel),
   2551                    ty,
   2552                }
   2553            } else {
   2554                match ty.kind {
   2555                    TypeKind::Struct(s) => {
   2556                        let sym = state.sym(s);
   2557                        let fields = match &sym.decl {
   2558                            SymDecl::Struct(fields) => fields,
   2559                            _ => panic!("expected struct"),
   2560                        };
   2561                        let field = fields
   2562                            .fields
   2563                            .iter()
   2564                            .find(|x| &x.name == i)
   2565                            .expect(&format!("missing field `{}` in `{}`", i, sym.name));
   2566                        Expr {
   2567                            kind: ExprKind::Dot(e, i.clone()),
   2568                            ty: field.ty.clone(),
   2569                        }
   2570                    }
   2571                    _ => panic!("expected struct found {:#?} {:#?}", e, ty),
   2572                }
   2573            }
   2574        }
   2575        syntax::Expr::Bracket(e, specifier) => {
   2576            let e = Box::new(translate_expression(state, e));
   2577            let ty = if let Some(ty) = index_vector(&e.ty) {
   2578                Type::new(ty)
   2579            } else if let Some(ty) = index_matrix(&e.ty) {
   2580                Type::new(ty)
   2581            } else {
   2582                let a = match &e.ty.array_sizes {
   2583                    Some(a) => {
   2584                        let mut a = *a.clone();
   2585                        a.sizes.pop();
   2586                        if a.sizes.len() == 0 {
   2587                            None
   2588                        } else {
   2589                            Some(Box::new(a))
   2590                        }
   2591                    }
   2592                    _ => panic!("{:#?}", e),
   2593                };
   2594                Type {
   2595                    kind: e.ty.kind.clone(),
   2596                    precision: e.ty.precision.clone(),
   2597                    array_sizes: a,
   2598                }
   2599            };
   2600            let indx = specifier.dimensions.0.iter().map(|a| match a {
   2601                ArraySpecifierDimension::Unsized => panic!("need expression"),
   2602                ArraySpecifierDimension::ExplicitlySized(e) => translate_expression(state, e),
   2603            }).collect();
   2604            Expr {
   2605                kind: ExprKind::Bracket(e, indx),
   2606                ty,
   2607            }
   2608        }
   2609    }
   2610 }
   2611 
   2612 fn translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement {
   2613    let mut cases = Vec::new();
   2614 
   2615    let mut case = None;
   2616    for stmt in &s.body {
   2617        match stmt {
   2618            syntax::Statement::Simple(s) => match &**s {
   2619                syntax::SimpleStatement::CaseLabel(label) => {
   2620                    match case.take() {
   2621                        Some(case) => cases.push(case),
   2622                        _ => {}
   2623                    }
   2624                    case = Some(Case {
   2625                        label: translate_case(state, &label),
   2626                        stmts: Vec::new(),
   2627                    })
   2628                }
   2629                _ => match case {
   2630                    Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
   2631                    _ => panic!("switch must start with case"),
   2632                },
   2633            },
   2634            _ => match case {
   2635                Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
   2636                _ => panic!("switch must start with case"),
   2637            },
   2638        }
   2639    }
   2640    match case.take() {
   2641        Some(case) => cases.push(case),
   2642        _ => {}
   2643    }
   2644    SwitchStatement {
   2645        head: Box::new(translate_expression(state, &s.head)),
   2646        cases,
   2647    }
   2648 }
   2649 
   2650 fn translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement {
   2651    match s {
   2652        syntax::JumpStatement::Break => JumpStatement::Break,
   2653        syntax::JumpStatement::Continue => JumpStatement::Continue,
   2654        syntax::JumpStatement::Discard => JumpStatement::Discard,
   2655        syntax::JumpStatement::Return(e) => {
   2656            JumpStatement::Return(e.as_ref().map(|e| Box::new(translate_expression(state, e))))
   2657        }
   2658    }
   2659 }
   2660 
   2661 fn translate_condition(state: &mut State, c: &syntax::Condition) -> Condition {
   2662    match c {
   2663        syntax::Condition::Expr(e) => Condition::Expr(Box::new(translate_expression(state, e))),
   2664        _ => panic!(),
   2665    }
   2666 }
   2667 
   2668 fn translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement {
   2669    match s {
   2670        syntax::ForInitStatement::Expression(e) => {
   2671            ForInitStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
   2672        }
   2673        syntax::ForInitStatement::Declaration(d) => ForInitStatement::Declaration(Box::new(
   2674            translate_declaration(state, d, RunClass::Scalar),
   2675        )),
   2676    }
   2677 }
   2678 
   2679 fn translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement {
   2680    ForRestStatement {
   2681        condition: s.condition.as_ref().map(|c| translate_condition(state, c)),
   2682        post_expr: s
   2683            .post_expr
   2684            .as_ref()
   2685            .map(|e| Box::new(translate_expression(state, e))),
   2686    }
   2687 }
   2688 
   2689 fn translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement {
   2690    match s {
   2691        syntax::IterationStatement::While(cond, s) => IterationStatement::While(
   2692            translate_condition(state, cond),
   2693            Box::new(translate_statement(state, s)),
   2694        ),
   2695        syntax::IterationStatement::For(init, rest, s) => IterationStatement::For(
   2696            translate_for_init(state, init),
   2697            translate_for_rest(state, rest),
   2698            Box::new(translate_statement(state, s)),
   2699        ),
   2700        syntax::IterationStatement::DoWhile(s, e) => IterationStatement::DoWhile(
   2701            Box::new(translate_statement(state, s)),
   2702            Box::new(translate_expression(state, e)),
   2703        ),
   2704    }
   2705 }
   2706 
   2707 fn translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel {
   2708    match c {
   2709        syntax::CaseLabel::Def => CaseLabel::Def,
   2710        syntax::CaseLabel::Case(e) => CaseLabel::Case(Box::new(translate_expression(state, e))),
   2711    }
   2712 }
   2713 
   2714 fn translate_selection_rest(
   2715    state: &mut State,
   2716    s: &syntax::SelectionRestStatement,
   2717 ) -> (Box<Statement>, Option<Box<Statement>>) {
   2718    match s {
   2719        syntax::SelectionRestStatement::Statement(s) => {
   2720            (Box::new(translate_statement(state, s)), None)
   2721        }
   2722        syntax::SelectionRestStatement::Else(if_body, rest) => (
   2723            Box::new(translate_statement(state, if_body)),
   2724            Some(Box::new(translate_statement(state, rest))),
   2725        ),
   2726    }
   2727 }
   2728 
   2729 fn translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement {
   2730    let cond = Box::new(translate_expression(state, &s.cond));
   2731    let (body, else_stmt) = translate_selection_rest(state, &s.rest);
   2732    SelectionStatement {
   2733        cond,
   2734        body,
   2735        else_stmt,
   2736    }
   2737 }
   2738 
   2739 fn translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement {
   2740    match s {
   2741        syntax::SimpleStatement::Declaration(d) => {
   2742            SimpleStatement::Declaration(translate_declaration(state, d, RunClass::Unknown))
   2743        }
   2744        syntax::SimpleStatement::Expression(e) => {
   2745            SimpleStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
   2746        }
   2747        syntax::SimpleStatement::Iteration(i) => {
   2748            SimpleStatement::Iteration(translate_iteration(state, i))
   2749        }
   2750        syntax::SimpleStatement::Selection(s) => {
   2751            SimpleStatement::Selection(translate_selection(state, s))
   2752        }
   2753        syntax::SimpleStatement::Jump(j) => SimpleStatement::Jump(translate_jump(state, j)),
   2754        syntax::SimpleStatement::Switch(s) => SimpleStatement::Switch(translate_switch(state, s)),
   2755        syntax::SimpleStatement::CaseLabel(_) => panic!("should be handled by translate_switch"),
   2756    }
   2757 }
   2758 
   2759 fn translate_statement(state: &mut State, s: &syntax::Statement) -> Statement {
   2760    match s {
   2761        syntax::Statement::Compound(s) => {
   2762            Statement::Compound(Box::new(translate_compound_statement(state, s)))
   2763        }
   2764        syntax::Statement::Simple(s) => {
   2765            Statement::Simple(Box::new(translate_simple_statement(state, s)))
   2766        }
   2767    }
   2768 }
   2769 
   2770 fn translate_compound_statement(
   2771    state: &mut State,
   2772    cs: &syntax::CompoundStatement,
   2773 ) -> CompoundStatement {
   2774    CompoundStatement {
   2775        statement_list: cs
   2776            .statement_list
   2777            .iter()
   2778            .map(|x| translate_statement(state, x))
   2779            .collect(),
   2780    }
   2781 }
   2782 
   2783 fn translate_function_parameter_declaration(
   2784    state: &mut State,
   2785    p: &syntax::FunctionParameterDeclaration,
   2786    index: usize,
   2787 ) -> FunctionParameterDeclaration {
   2788    match p {
   2789        syntax::FunctionParameterDeclaration::Named(qual, p) => {
   2790            let mut ty: Type = lift(state, &p.ty);
   2791            if let Some(a) = &p.ident.array_spec {
   2792                ty.array_sizes = Some(Box::new(lift(state, a)));
   2793            }
   2794 
   2795            ty.precision = get_precision(qual);
   2796 
   2797            let decl = SymDecl::Local(
   2798                StorageClass::None,
   2799                ty.clone(),
   2800                RunClass::Dependent(1 << index),
   2801            );
   2802            let d = FunctionParameterDeclarator {
   2803                ty,
   2804                name: p.ident.ident.clone(),
   2805                sym: state.declare(p.ident.ident.as_str(), decl),
   2806            };
   2807            FunctionParameterDeclaration::Named(lift_type_qualifier_for_parameter(state, qual), d)
   2808        }
   2809        syntax::FunctionParameterDeclaration::Unnamed(qual, p) => {
   2810            FunctionParameterDeclaration::Unnamed(
   2811                lift_type_qualifier_for_parameter(state, qual),
   2812                p.clone(),
   2813            )
   2814        }
   2815    }
   2816 }
   2817 
   2818 fn translate_prototype(
   2819    state: &mut State,
   2820    cs: &syntax::FunctionPrototype,
   2821 ) -> (FunctionPrototype, SymRef) {
   2822    let prototype = FunctionPrototype {
   2823        ty: lift(state, &cs.ty),
   2824        name: cs.name.clone(),
   2825        parameters: cs
   2826            .parameters
   2827            .iter()
   2828            .enumerate()
   2829            .map(|(i, x)| translate_function_parameter_declaration(state, x, i))
   2830            .collect(),
   2831    };
   2832    let sym = if let Some(sym) = state.lookup(prototype.name.as_str()) {
   2833        match &state.sym(sym).decl {
   2834            SymDecl::UserFunction(..) => {}
   2835            _ => panic!(
   2836                "prototype conflicts with existing symbol: {}",
   2837                prototype.name.as_str()
   2838            ),
   2839        }
   2840        sym
   2841    } else {
   2842        let pfd = Rc::new(FunctionDefinition {
   2843            prototype: prototype.clone(),
   2844            body: CompoundStatement::new(),
   2845            globals: Vec::new(),
   2846            texel_fetches: HashMap::new(),
   2847        });
   2848        state.declare(
   2849            prototype.name.as_str(),
   2850            SymDecl::UserFunction(pfd, RunClass::Unknown),
   2851        )
   2852    };
   2853    (prototype, sym)
   2854 }
   2855 
   2856 fn translate_function_prototype(
   2857    state: &mut State,
   2858    prototype: &syntax::FunctionPrototype,
   2859 ) -> FunctionPrototype {
   2860    let (prototype, _) = translate_prototype(state, prototype);
   2861    prototype
   2862 }
   2863 
   2864 fn translate_function_definition(
   2865    state: &mut State,
   2866    sfd: &syntax::FunctionDefinition,
   2867 ) -> Rc<FunctionDefinition> {
   2868    let (prototype, sym) = translate_prototype(state, &sfd.prototype);
   2869 
   2870    state.push_scope(prototype.name.as_str().into());
   2871    state.in_function = Some(sym);
   2872    state.modified_globals.get_mut().clear();
   2873    state.texel_fetches.clear();
   2874    let body = translate_compound_statement(state, &sfd.statement);
   2875    let mut globals = Vec::new();
   2876    mem::swap(&mut globals, state.modified_globals.get_mut());
   2877    let mut texel_fetches = HashMap::new();
   2878    mem::swap(&mut texel_fetches, &mut state.texel_fetches);
   2879    state.in_function = None;
   2880    state.pop_scope();
   2881 
   2882    let fd = Rc::new(FunctionDefinition {
   2883        prototype,
   2884        body,
   2885        globals,
   2886        texel_fetches,
   2887    });
   2888    state.sym_mut(sym).decl = SymDecl::UserFunction(fd.clone(), RunClass::Unknown);
   2889    fd
   2890 }
   2891 
   2892 fn translate_external_declaration(
   2893    state: &mut State,
   2894    ed: &syntax::ExternalDeclaration,
   2895 ) -> ExternalDeclaration {
   2896    match ed {
   2897        syntax::ExternalDeclaration::Declaration(d) => {
   2898            ExternalDeclaration::Declaration(translate_declaration(state, d, RunClass::Unknown))
   2899        }
   2900        syntax::ExternalDeclaration::FunctionDefinition(fd) => {
   2901            ExternalDeclaration::FunctionDefinition(translate_function_definition(state, fd))
   2902        }
   2903        syntax::ExternalDeclaration::Preprocessor(p) => {
   2904            ExternalDeclaration::Preprocessor(p.clone())
   2905        }
   2906    }
   2907 }
   2908 
   2909 fn declare_function_ext(
   2910    state: &mut State,
   2911    name: &str,
   2912    cxx_name: Option<&'static str>,
   2913    ret: Type,
   2914    params: Vec<Type>,
   2915    run_class: RunClass,
   2916 ) {
   2917    let sig = FunctionSignature { ret, params };
   2918    match state.lookup_sym_mut(name) {
   2919        Some(Symbol {
   2920            decl: SymDecl::NativeFunction(f, ..),
   2921            ..
   2922        }) => f.signatures.push(sig),
   2923        None => {
   2924            state.declare(
   2925                name,
   2926                SymDecl::NativeFunction(
   2927                    FunctionType {
   2928                        signatures: NonEmpty::new(sig),
   2929                    },
   2930                    cxx_name,
   2931                    run_class,
   2932                ),
   2933            );
   2934        }
   2935        _ => panic!("overloaded function name {}", name),
   2936    }
   2937    //state.declare(name, Type::Function(FunctionType{ v}))
   2938 }
   2939 
   2940 fn declare_function(
   2941    state: &mut State,
   2942    name: &str,
   2943    cxx_name: Option<&'static str>,
   2944    ret: Type,
   2945    params: Vec<Type>,
   2946 ) {
   2947    declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown)
   2948 }
   2949 
   2950 pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit {
   2951    // global scope
   2952    state.push_scope("global".into());
   2953    use TypeKind::*;
   2954    declare_function(
   2955        state,
   2956        "vec2",
   2957        Some("make_vec2"),
   2958        Type::new(Vec2),
   2959        vec![Type::new(Float)],
   2960    );
   2961    declare_function(
   2962        state,
   2963        "vec2",
   2964        Some("make_vec2"),
   2965        Type::new(Vec2),
   2966        vec![Type::new(Float), Type::new(Float)],
   2967    );
   2968    declare_function(
   2969        state,
   2970        "vec2",
   2971        Some("make_vec2"),
   2972        Type::new(Vec2),
   2973        vec![Type::new(IVec2)],
   2974    );
   2975    declare_function(
   2976        state,
   2977        "vec2",
   2978        Some("make_vec2"),
   2979        Type::new(Vec2),
   2980        vec![Type::new(IVec3)],
   2981    );
   2982    declare_function(
   2983        state,
   2984        "vec3",
   2985        Some("make_vec3"),
   2986        Type::new(Vec3),
   2987        vec![Type::new(Float), Type::new(Float), Type::new(Float)],
   2988    );
   2989    declare_function(
   2990        state,
   2991        "vec3",
   2992        Some("make_vec3"),
   2993        Type::new(Vec3),
   2994        vec![Type::new(Float)],
   2995    );
   2996    declare_function(
   2997        state,
   2998        "vec3",
   2999        Some("make_vec3"),
   3000        Type::new(Vec3),
   3001        vec![Type::new(Vec2), Type::new(Float)],
   3002    );
   3003    declare_function(
   3004        state,
   3005        "vec4",
   3006        Some("make_vec4"),
   3007        Type::new(Vec4),
   3008        vec![Type::new(Float)],
   3009    );
   3010    declare_function(
   3011        state,
   3012        "vec4",
   3013        Some("make_vec4"),
   3014        Type::new(Vec4),
   3015        vec![Type::new(Vec3), Type::new(Float)],
   3016    );
   3017    declare_function(
   3018        state,
   3019        "vec4",
   3020        Some("make_vec4"),
   3021        Type::new(Vec4),
   3022        vec![
   3023            Type::new(Float),
   3024            Type::new(Float),
   3025            Type::new(Float),
   3026            Type::new(Float),
   3027        ],
   3028    );
   3029    declare_function(
   3030        state,
   3031        "vec4",
   3032        Some("make_vec4"),
   3033        Type::new(Vec4),
   3034        vec![Type::new(Vec2), Type::new(Float), Type::new(Float)],
   3035    );
   3036    declare_function(
   3037        state,
   3038        "vec4",
   3039        Some("make_vec4"),
   3040        Type::new(Vec4),
   3041        vec![Type::new(Vec2), Type::new(Vec2)],
   3042    );
   3043    declare_function(
   3044        state,
   3045        "vec4",
   3046        Some("make_vec4"),
   3047        Type::new(Vec4),
   3048        vec![Type::new(Float), Type::new(Float), Type::new(Vec2)],
   3049    );
   3050    declare_function(
   3051        state,
   3052        "vec4",
   3053        Some("make_vec4"),
   3054        Type::new(Vec4),
   3055        vec![Type::new(Vec4)],
   3056    );
   3057    declare_function(
   3058        state,
   3059        "vec4",
   3060        Some("make_vec4"),
   3061        Type::new(Vec4),
   3062        vec![Type::new(IVec4)],
   3063    );
   3064 
   3065    declare_function(
   3066        state,
   3067        "bvec2",
   3068        Some("make_bvec2"),
   3069        Type::new(BVec2),
   3070        vec![Type::new(Bool)],
   3071    );
   3072    declare_function(
   3073        state,
   3074        "bvec3",
   3075        Some("make_bvec3"),
   3076        Type::new(BVec3),
   3077        vec![Type::new(Bool)],
   3078    );
   3079    declare_function(
   3080        state,
   3081        "bvec4",
   3082        Some("make_bvec4"),
   3083        Type::new(BVec4),
   3084        vec![Type::new(Bool)],
   3085    );
   3086    declare_function(
   3087        state,
   3088        "bvec4",
   3089        Some("make_bvec4"),
   3090        Type::new(BVec4),
   3091        vec![Type::new(BVec2), Type::new(BVec2)],
   3092    );
   3093    declare_function(
   3094        state,
   3095        "bvec4",
   3096        Some("make_bvec4"),
   3097        Type::new(BVec4),
   3098        vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)],
   3099    );
   3100    declare_function(
   3101        state,
   3102        "int",
   3103        Some("make_int"),
   3104        Type::new(Int),
   3105        vec![Type::new(Float)],
   3106    );
   3107    declare_function(
   3108        state,
   3109        "float",
   3110        Some("make_float"),
   3111        Type::new(Float),
   3112        vec![Type::new(Float)],
   3113    );
   3114    declare_function(
   3115        state,
   3116        "float",
   3117        Some("make_float"),
   3118        Type::new(Float),
   3119        vec![Type::new(Int)],
   3120    );
   3121    declare_function(
   3122        state,
   3123        "int",
   3124        Some("make_int"),
   3125        Type::new(Int),
   3126        vec![Type::new(UInt)],
   3127    );
   3128    declare_function(
   3129        state,
   3130        "uint",
   3131        Some("make_uint"),
   3132        Type::new(UInt),
   3133        vec![Type::new(Float)],
   3134    );
   3135    declare_function(
   3136        state,
   3137        "uint",
   3138        Some("make_uint"),
   3139        Type::new(UInt),
   3140        vec![Type::new(Int)],
   3141    );
   3142    declare_function(
   3143        state,
   3144        "ivec2",
   3145        Some("make_ivec2"),
   3146        Type::new(IVec2),
   3147        vec![Type::new(UInt), Type::new(UInt)],
   3148    );
   3149    declare_function(
   3150        state,
   3151        "ivec2",
   3152        Some("make_ivec2"),
   3153        Type::new(IVec2),
   3154        vec![Type::new(Int), Type::new(Int)],
   3155    );
   3156    declare_function(
   3157        state,
   3158        "ivec2",
   3159        Some("make_ivec2"),
   3160        Type::new(IVec2),
   3161        vec![Type::new(Vec2)],
   3162    );
   3163    declare_function(
   3164        state,
   3165        "ivec3",
   3166        Some("make_ivec3"),
   3167        Type::new(IVec3),
   3168        vec![Type::new(IVec2), Type::new(Int)],
   3169    );
   3170    declare_function(
   3171        state,
   3172        "ivec4",
   3173        Some("make_ivec4"),
   3174        Type::new(IVec4),
   3175        vec![
   3176            Type::new(Int),
   3177            Type::new(Int),
   3178            Type::new(Int),
   3179            Type::new(Int),
   3180        ],
   3181    );
   3182    declare_function(
   3183        state,
   3184        "ivec4",
   3185        Some("make_ivec4"),
   3186        Type::new(IVec4),
   3187        vec![Type::new(Vec4)],
   3188    );
   3189    declare_function(
   3190        state,
   3191        "ivec4",
   3192        Some("make_ivec4"),
   3193        Type::new(IVec4),
   3194        vec![Type::new(IVec2), Type::new(Int), Type::new(Int)],
   3195    );
   3196 
   3197    declare_function(
   3198        state,
   3199        "mat2",
   3200        Some("make_mat2"),
   3201        Type::new(Mat2),
   3202        vec![Type::new(Vec2), Type::new(Vec2)],
   3203    );
   3204    declare_function(
   3205        state,
   3206        "mat2",
   3207        Some("make_mat2"),
   3208        Type::new(Mat2),
   3209        vec![Type::new(Float)],
   3210    );
   3211    declare_function(
   3212        state,
   3213        "mat2",
   3214        Some("make_mat2"),
   3215        Type::new(Mat2),
   3216        vec![Type::new(Mat4)],
   3217    );
   3218    declare_function(
   3219        state,
   3220        "mat3",
   3221        Some("make_mat3"),
   3222        Type::new(Mat3),
   3223        vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
   3224    );
   3225    declare_function(
   3226        state,
   3227        "mat3",
   3228        Some("make_mat3"),
   3229        Type::new(Mat3),
   3230        vec![Type::new(Mat4)],
   3231    );
   3232    declare_function(
   3233        state,
   3234        "mat3",
   3235        Some("make_mat3"),
   3236        Type::new(Mat3),
   3237        vec![
   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            Type::new(Float),
   3246            Type::new(Float),
   3247        ],
   3248    );
   3249    declare_function(
   3250        state,
   3251        "mat3x4",
   3252        Some("make_mat3x4"),
   3253        Type::new(Mat34),
   3254        vec![
   3255            Type::new(Float),
   3256            Type::new(Float),
   3257            Type::new(Float),
   3258            Type::new(Float),
   3259 
   3260            Type::new(Float),
   3261            Type::new(Float),
   3262            Type::new(Float),
   3263            Type::new(Float),
   3264 
   3265            Type::new(Float),
   3266            Type::new(Float),
   3267            Type::new(Float),
   3268            Type::new(Float),
   3269        ],
   3270    );
   3271    declare_function(
   3272        state,
   3273        "transpose",
   3274        None,
   3275        Type::new(Mat43),
   3276        vec![Type::new(Mat34)],
   3277    );
   3278    declare_function(
   3279        state,
   3280        "mat4",
   3281        Some("make_mat4"),
   3282        Type::new(Mat4),
   3283        vec![
   3284            Type::new(Vec4),
   3285            Type::new(Vec4),
   3286            Type::new(Vec4),
   3287            Type::new(Vec4),
   3288        ],
   3289    );
   3290    declare_function(
   3291        state,
   3292        "mat4",
   3293        Some("make_mat4"),
   3294        Type::new(Mat4),
   3295        vec![
   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            Type::new(Float),
   3311            Type::new(Float),
   3312        ],
   3313    );
   3314    declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]);
   3315    declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]);
   3316    declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]);
   3317    declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]);
   3318    declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]);
   3319    declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]);
   3320    declare_function(
   3321        state,
   3322        "dot",
   3323        None,
   3324        Type::new(Float),
   3325        vec![Type::new(Vec3), Type::new(Vec3)],
   3326    );
   3327    declare_function(
   3328        state,
   3329        "dot",
   3330        None,
   3331        Type::new(Float),
   3332        vec![Type::new(Vec2), Type::new(Vec2)],
   3333    );
   3334    for t in &[Vec2, Vec3, Vec4] {
   3335        declare_function(
   3336            state,
   3337            "min",
   3338            None,
   3339            Type::new(*t),
   3340            vec![Type::new(*t), Type::new(Float)],
   3341        );
   3342        declare_function(
   3343            state,
   3344            "max",
   3345            None,
   3346            Type::new(*t),
   3347            vec![Type::new(*t), Type::new(Float)],
   3348        );
   3349    }
   3350    for t in &[Int, Float, Vec2, Vec3, Vec4] {
   3351        declare_function(
   3352            state,
   3353            "min",
   3354            None,
   3355            Type::new(*t),
   3356            vec![Type::new(*t), Type::new(*t)],
   3357        );
   3358        declare_function(
   3359            state,
   3360            "max",
   3361            None,
   3362            Type::new(*t),
   3363            vec![Type::new(*t), Type::new(*t)],
   3364        );
   3365    }
   3366 
   3367    declare_function(
   3368        state,
   3369        "mix",
   3370        None,
   3371        Type::new(Vec2),
   3372        vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
   3373    );
   3374    declare_function(
   3375        state,
   3376        "mix",
   3377        None,
   3378        Type::new(Vec2),
   3379        vec![Type::new(Vec2), Type::new(Vec2), Type::new(BVec2)],
   3380    );
   3381    declare_function(
   3382        state,
   3383        "mix",
   3384        None,
   3385        Type::new(Vec2),
   3386        vec![Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
   3387    );
   3388    declare_function(
   3389        state,
   3390        "mix",
   3391        None,
   3392        Type::new(Vec3),
   3393        vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
   3394    );
   3395    declare_function(
   3396        state,
   3397        "mix",
   3398        None,
   3399        Type::new(Vec4),
   3400        vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
   3401    );
   3402    declare_function(
   3403        state,
   3404        "mix",
   3405        None,
   3406        Type::new(Vec4),
   3407        vec![Type::new(Vec4), Type::new(Vec4), Type::new(Float)],
   3408    );
   3409    declare_function(
   3410        state,
   3411        "mix",
   3412        None,
   3413        Type::new(Vec3),
   3414        vec![Type::new(Vec3), Type::new(Vec3), Type::new(Float)],
   3415    );
   3416    declare_function(
   3417        state,
   3418        "mix",
   3419        None,
   3420        Type::new(Vec3),
   3421        vec![Type::new(Vec3), Type::new(Vec3), Type::new(BVec3)],
   3422    );
   3423    declare_function(
   3424        state,
   3425        "mix",
   3426        None,
   3427        Type::new(Float),
   3428        vec![Type::new(Float), Type::new(Float), Type::new(Float)],
   3429    );
   3430    declare_function(
   3431        state,
   3432        "mix",
   3433        None,
   3434        Type::new(Vec4),
   3435        vec![Type::new(Vec4), Type::new(Vec4), Type::new(BVec4)],
   3436    );
   3437    declare_function(
   3438        state,
   3439        "step",
   3440        None,
   3441        Type::new(Float),
   3442        vec![Type::new(Float), Type::new(Float)],
   3443    );
   3444    declare_function(
   3445        state,
   3446        "step",
   3447        None,
   3448        Type::new(Vec2),
   3449        vec![Type::new(Vec2), Type::new(Vec2)],
   3450    );
   3451    declare_function(
   3452        state,
   3453        "step",
   3454        None,
   3455        Type::new(Vec2),
   3456        vec![Type::new(Float), Type::new(Vec2)],
   3457    );
   3458    declare_function(
   3459        state,
   3460        "step",
   3461        None,
   3462        Type::new(Vec3),
   3463        vec![Type::new(Vec3), Type::new(Vec3)],
   3464    );
   3465    declare_function(
   3466        state,
   3467        "step",
   3468        None,
   3469        Type::new(Vec4),
   3470        vec![Type::new(Float), Type::new(Vec4)],
   3471    );
   3472    declare_function(
   3473        state,
   3474        "notEqual",
   3475        None,
   3476        Type::new(BVec4),
   3477        vec![Type::new(IVec4), Type::new(IVec4)],
   3478    );
   3479 
   3480    declare_function_ext(
   3481        state,
   3482        "fwidth",
   3483        None,
   3484        Type::new(Vec2),
   3485        vec![Type::new(Vec2)],
   3486        RunClass::Scalar,
   3487    );
   3488    declare_function_ext(
   3489        state,
   3490        "dFdx",
   3491        None,
   3492        Type::new(Float),
   3493        vec![Type::new(Float)],
   3494        RunClass::Scalar,
   3495    );
   3496    declare_function_ext(
   3497        state,
   3498        "dFdx",
   3499        None,
   3500        Type::new(Vec2),
   3501        vec![Type::new(Vec2)],
   3502        RunClass::Scalar,
   3503    );
   3504 
   3505    declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
   3506    declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
   3507    declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
   3508    declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
   3509    declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
   3510    for t in &[Vec2, Vec3, Vec4] {
   3511        declare_function(
   3512            state,
   3513            "clamp",
   3514            None,
   3515            Type::new(*t),
   3516            vec![Type::new(*t), Type::new(Float), Type::new(Float)],
   3517        );
   3518    }
   3519    for t in &[Float, Vec2, Vec3, Vec4] {
   3520        declare_function(
   3521            state,
   3522            "clamp",
   3523            None,
   3524            Type::new(*t),
   3525            vec![Type::new(*t), Type::new(*t), Type::new(*t)],
   3526        );
   3527    }
   3528    declare_function(
   3529        state,
   3530        "length",
   3531        None,
   3532        Type::new(Float),
   3533        vec![Type::new(Vec2)],
   3534    );
   3535    declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
   3536    declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
   3537    declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
   3538    declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]);
   3539    declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]);
   3540    declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]);
   3541    for t in &[Float, Vec2] {
   3542        // recip is non-standard
   3543        declare_function(
   3544            state,
   3545            "recip",
   3546            None,
   3547            Type::new(*t),
   3548            vec![Type::new(*t)],
   3549        );
   3550        declare_function(
   3551            state,
   3552            "inversesqrt",
   3553            None,
   3554            Type::new(*t),
   3555            vec![Type::new(*t)],
   3556        );
   3557        declare_function(
   3558            state,
   3559            "sqrt",
   3560            None,
   3561            Type::new(*t),
   3562            vec![Type::new(*t)],
   3563        );
   3564    }
   3565    declare_function(
   3566        state,
   3567        "distance",
   3568        None,
   3569        Type::new(Float),
   3570        vec![Type::new(Vec2), Type::new(Vec2)],
   3571    );
   3572 
   3573    declare_function(
   3574        state,
   3575        "equal",
   3576        None,
   3577        Type::new(BVec2),
   3578        vec![Type::new(Vec2), Type::new(Vec2)],
   3579    );
   3580    declare_function(
   3581        state,
   3582        "equal",
   3583        None,
   3584        Type::new(BVec4),
   3585        vec![Type::new(Vec4), Type::new(Vec4)],
   3586    );
   3587    declare_function(
   3588        state,
   3589        "notEqual",
   3590        None,
   3591        Type::new(BVec2),
   3592        vec![Type::new(Vec2), Type::new(Vec2)],
   3593    );
   3594    declare_function(
   3595        state,
   3596        "notEqual",
   3597        None,
   3598        Type::new(BVec4),
   3599        vec![Type::new(Vec4), Type::new(Vec4)],
   3600    );
   3601    declare_function(
   3602        state,
   3603        "lessThanEqual",
   3604        None,
   3605        Type::new(BVec2),
   3606        vec![Type::new(Vec2), Type::new(Vec2)],
   3607    );
   3608    declare_function(
   3609        state,
   3610        "lessThanEqual",
   3611        None,
   3612        Type::new(BVec3),
   3613        vec![Type::new(Vec3), Type::new(Vec3)],
   3614    );
   3615    declare_function(
   3616        state,
   3617        "lessThanEqual",
   3618        None,
   3619        Type::new(BVec4),
   3620        vec![Type::new(Vec4), Type::new(Vec4)],
   3621    );
   3622    declare_function(
   3623        state,
   3624        "lessThan",
   3625        None,
   3626        Type::new(BVec2),
   3627        vec![Type::new(Vec2), Type::new(Vec2)],
   3628    );
   3629    declare_function(
   3630        state,
   3631        "lessThan",
   3632        None,
   3633        Type::new(BVec4),
   3634        vec![Type::new(Vec4), Type::new(Vec4)],
   3635    );
   3636    declare_function(
   3637        state,
   3638        "greaterThan",
   3639        None,
   3640        Type::new(BVec2),
   3641        vec![Type::new(Vec2), Type::new(Vec2)],
   3642    );
   3643    declare_function(
   3644        state,
   3645        "greaterThan",
   3646        None,
   3647        Type::new(BVec4),
   3648        vec![Type::new(Vec4), Type::new(Vec4)],
   3649    );
   3650    declare_function(
   3651        state,
   3652        "greaterThanEqual",
   3653        None,
   3654        Type::new(BVec2),
   3655        vec![Type::new(Vec2), Type::new(Vec2)],
   3656    );
   3657    declare_function(
   3658        state,
   3659        "greaterThanEqual",
   3660        None,
   3661        Type::new(BVec4),
   3662        vec![Type::new(Vec4), Type::new(Vec4)],
   3663    );
   3664    declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]);
   3665    declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec4)]);
   3666    declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec2)]);
   3667    declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec4)]);
   3668 
   3669    declare_function(
   3670        state,
   3671        "if_then_else",
   3672        None,
   3673        Type::new(Vec3),
   3674        vec![Type::new(BVec3), Type::new(Vec3), Type::new(Vec3)],
   3675    );
   3676    declare_function(state, "floor", None, Type::new(Vec4), vec![Type::new(Vec4)]);
   3677    declare_function(state, "floor", None, Type::new(Vec2), vec![Type::new(Vec2)]);
   3678    declare_function(
   3679        state,
   3680        "floor",
   3681        None,
   3682        Type::new(Float),
   3683        vec![Type::new(Float)],
   3684    );
   3685    declare_function(
   3686        state,
   3687        "ceil",
   3688        None,
   3689        Type::new(Float),
   3690        vec![Type::new(Float)],
   3691    );
   3692    declare_function(
   3693        state,
   3694        "round",
   3695        None,
   3696        Type::new(Float),
   3697        vec![Type::new(Float)],
   3698    );
   3699    declare_function(
   3700        state,
   3701        "fract",
   3702        None,
   3703        Type::new(Float),
   3704        vec![Type::new(Float)],
   3705    );
   3706    declare_function(
   3707        state,
   3708        "fract",
   3709        None,
   3710        Type::new(Vec2),
   3711        vec![Type::new(Vec2)],
   3712    );
   3713    declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
   3714    declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);
   3715 
   3716    declare_function(
   3717        state,
   3718        "texelFetch",
   3719        None,
   3720        Type::new(Vec4),
   3721        vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
   3722    );
   3723    declare_function(
   3724        state,
   3725        "texelFetch",
   3726        None,
   3727        Type::new(IVec4),
   3728        vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)],
   3729    );
   3730    declare_function(
   3731        state,
   3732        "texelFetchOffset",
   3733        None,
   3734        Type::new(Vec4),
   3735        vec![
   3736            Type::new(Sampler2D),
   3737            Type::new(IVec2),
   3738            Type::new(Int),
   3739            Type::new(IVec2),
   3740        ],
   3741    );
   3742    declare_function(
   3743        state,
   3744        "texelFetchOffset",
   3745        None,
   3746        Type::new(IVec4),
   3747        vec![
   3748            Type::new(ISampler2D),
   3749            Type::new(IVec2),
   3750            Type::new(Int),
   3751            Type::new(IVec2),
   3752        ],
   3753    );
   3754    declare_function(
   3755        state,
   3756        "texture",
   3757        None,
   3758        Type::new(Vec4),
   3759        vec![Type::new(Sampler2D), Type::new(Vec2)],
   3760    );
   3761    declare_function(
   3762        state,
   3763        "texture",
   3764        None,
   3765        Type::new(Vec4),
   3766        vec![Type::new(Sampler2DRect), Type::new(Vec2)],
   3767    );
   3768    declare_function(
   3769        state,
   3770        "textureSize",
   3771        None,
   3772        Type::new(IVec2),
   3773        vec![Type::new(Sampler2D), Type::new(Int)],
   3774    );
   3775    declare_function(
   3776        state,
   3777        "textureSize",
   3778        None,
   3779        Type::new(IVec2),
   3780        vec![Type::new(Sampler2DRect), Type::new(Int)],
   3781    );
   3782 
   3783    declare_function(
   3784        state,
   3785        "inverse",
   3786        None,
   3787        Type::new(Mat2),
   3788        vec![Type::new(Mat2)],
   3789    );
   3790    declare_function(
   3791        state,
   3792        "transpose",
   3793        None,
   3794        Type::new(Mat3),
   3795        vec![Type::new(Mat3)],
   3796    );
   3797    declare_function(
   3798        state,
   3799        "normalize",
   3800        None,
   3801        Type::new(Vec2),
   3802        vec![Type::new(Vec2)],
   3803    );
   3804    state.declare(
   3805        "gl_FragCoord",
   3806        SymDecl::Global(StorageClass::In, None, Type::new(Vec4), RunClass::Vector),
   3807    );
   3808    state.declare(
   3809        "gl_FragColor",
   3810        SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
   3811    );
   3812    state.declare(
   3813        "gl_Position",
   3814        SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
   3815    );
   3816    state.clip_dist_sym = state.declare(
   3817        "gl_ClipDistance",
   3818        SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector),
   3819    );
   3820 
   3821    state.declare(
   3822        "swgl_SpanLength",
   3823        SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar),
   3824    );
   3825    state.declare(
   3826        "swgl_StepSize",
   3827        SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar),
   3828    );
   3829 
   3830    for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] {
   3831        declare_function_ext(
   3832            state,
   3833            "swgl_forceScalar",
   3834            None,
   3835            Type::new(*t),
   3836            vec![Type::new(*t)],
   3837            RunClass::Scalar,
   3838        );
   3839    }
   3840 
   3841    // GL_ARB_shader_group_vote
   3842    for (name, cxx_name) in &[("anyInvocations", "test_any"),
   3843                              ("allInvocations", "test_all"),
   3844                              ("allInvocationsEqual", "test_equal")] {
   3845        declare_function_ext(
   3846            state,
   3847            name,
   3848            Some(cxx_name),
   3849            Type::new(Bool),
   3850            vec![Type::new(Bool)],
   3851            RunClass::Scalar,
   3852        );
   3853    }
   3854 
   3855    declare_function(
   3856        state,
   3857        "swgl_stepInterp",
   3858        None,
   3859        Type::new(Void),
   3860        vec![],
   3861    );
   3862 
   3863    for t in &[Float, Vec2, Vec3, Vec4] {
   3864        declare_function_ext(
   3865            state,
   3866            "swgl_interpStep",
   3867            None,
   3868            Type::new(*t),
   3869            vec![Type::new(*t)],
   3870            RunClass::Scalar,
   3871        );
   3872    }
   3873 
   3874    declare_function(
   3875        state,
   3876        "swgl_commitPartialSolidRGBA8",
   3877        None,
   3878        Type::new(Void),
   3879        vec![Type::new(Int), Type::new(Vec4)],
   3880    );
   3881    declare_function(
   3882        state,
   3883        "swgl_commitPartialSolidR8",
   3884        None,
   3885        Type::new(Void),
   3886        vec![Type::new(Int), Type::new(Float)],
   3887    );
   3888    declare_function(
   3889        state,
   3890        "swgl_commitSolidRGBA8",
   3891        None,
   3892        Type::new(Void),
   3893        vec![Type::new(Vec4)],
   3894    );
   3895    declare_function(
   3896        state,
   3897        "swgl_commitSolidR8",
   3898        None,
   3899        Type::new(Void),
   3900        vec![Type::new(Float)],
   3901    );
   3902    declare_function(
   3903        state,
   3904        "swgl_commitColorRGBA8",
   3905        None,
   3906        Type::new(Void),
   3907        vec![Type::new(Vec4)],
   3908    );
   3909    declare_function(
   3910        state,
   3911        "swgl_commitColorR8",
   3912        None,
   3913        Type::new(Void),
   3914        vec![Type::new(Float)],
   3915    );
   3916    declare_function(
   3917        state,
   3918        "swgl_blendDropShadow",
   3919        None,
   3920        Type::new(Void),
   3921        vec![Type::new(Vec4)],
   3922    );
   3923    declare_function(
   3924        state,
   3925        "swgl_blendSubpixelText",
   3926        None,
   3927        Type::new(Void),
   3928        vec![Type::new(Vec4)],
   3929    );
   3930    declare_function(
   3931        state,
   3932        "swgl_clipMask",
   3933        None,
   3934        Type::new(Void),
   3935        vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
   3936    );
   3937    declare_function(
   3938        state,
   3939        "swgl_antiAlias",
   3940        None,
   3941        Type::new(Void),
   3942        vec![Type::new(Int)],
   3943    );
   3944    declare_function(
   3945        state,
   3946        "swgl_antiAlias",
   3947        None,
   3948        Type::new(Void),
   3949        vec![Type::new(BVec4)],
   3950    );
   3951    declare_function_ext(
   3952        state,
   3953        "swgl_validateGradient",
   3954        None,
   3955        Type::new(Int),
   3956        vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
   3957        RunClass::Scalar,
   3958    );
   3959    declare_function_ext(
   3960        state,
   3961        "swgl_validateGradientFromStops",
   3962        None,
   3963        Type::new(Int),
   3964        vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
   3965        RunClass::Scalar,
   3966    );
   3967    declare_function(
   3968        state,
   3969        "swgl_commitLinearGradientRGBA8",
   3970        None,
   3971        Type::new(Void),
   3972        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Bool),
   3973             Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
   3974    );
   3975    declare_function(
   3976        state,
   3977        "swgl_commitDitheredLinearGradientRGBA8",
   3978        None,
   3979        Type::new(Void),
   3980        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Bool),
   3981             Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
   3982    );
   3983    declare_function(
   3984        state,
   3985        "swgl_commitLinearGradientFromStopsRGBA8",
   3986        None,
   3987        Type::new(Void),
   3988        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool),
   3989             Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
   3990    );
   3991    declare_function(
   3992        state,
   3993        "swgl_commitDitheredLinearGradientFromStopsRGBA8",
   3994        None,
   3995        Type::new(Void),
   3996        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool),
   3997             Type::new(Vec2), Type::new(Vec2), Type::new(Float), Type::new(Vec4)],
   3998    );
   3999    declare_function(
   4000        state,
   4001        "swgl_commitRadialGradientRGBA8",
   4002        None,
   4003        Type::new(Void),
   4004        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
   4005             Type::new(Float)],
   4006    );
   4007    declare_function(
   4008        state,
   4009        "swgl_commitDitheredRadialGradientRGBA8",
   4010        None,
   4011        Type::new(Void),
   4012        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
   4013             Type::new(Float)],
   4014    );
   4015    declare_function(
   4016        state,
   4017        "swgl_commitRadialGradientFromStopsRGBA8",
   4018        None,
   4019        Type::new(Void),
   4020        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
   4021             Type::new(Float)],
   4022    );
   4023    declare_function(
   4024        state,
   4025        "swgl_commitDitheredRadialGradientFromStopsRGBA8",
   4026        None,
   4027        Type::new(Void),
   4028        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
   4029             Type::new(Float)],
   4030    );
   4031    declare_function(
   4032        state,
   4033        "swgl_commitGradientRGBA8",
   4034        None,
   4035        Type::new(Void),
   4036        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)],
   4037    );
   4038    declare_function(
   4039        state,
   4040        "swgl_commitGradientColorRGBA8",
   4041        None,
   4042        Type::new(Void),
   4043        vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)],
   4044    );
   4045    for s in &[Sampler2D, Sampler2DRect] {
   4046        declare_function_ext(
   4047            state,
   4048            "swgl_isTextureLinear",
   4049            None,
   4050            Type::new(Bool),
   4051            vec![Type::new(*s)],
   4052            RunClass::Scalar,
   4053        );
   4054        declare_function_ext(
   4055            state,
   4056            "swgl_isTextureRGBA8",
   4057            None,
   4058            Type::new(Bool),
   4059            vec![Type::new(*s)],
   4060            RunClass::Scalar,
   4061        );
   4062        declare_function_ext(
   4063            state,
   4064            "swgl_isTextureR8",
   4065            None,
   4066            Type::new(Bool),
   4067            vec![Type::new(*s)],
   4068            RunClass::Scalar,
   4069        );
   4070        declare_function(
   4071            state,
   4072            "swgl_commitTextureLinearRGBA8",
   4073            None,
   4074            Type::new(Void),
   4075            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4076        );
   4077        declare_function(
   4078            state,
   4079            "swgl_commitTextureLinearR8",
   4080            None,
   4081            Type::new(Void),
   4082            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4083        );
   4084        declare_function(
   4085            state,
   4086            "swgl_commitTextureLinearR8ToRGBA8",
   4087            None,
   4088            Type::new(Void),
   4089            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4090        );
   4091        declare_function(
   4092            state,
   4093            "swgl_commitPartialTextureLinearR8",
   4094            None,
   4095            Type::new(Void),
   4096            vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4097        );
   4098        declare_function(
   4099            state,
   4100            "swgl_commitPartialTextureLinearInvertR8",
   4101            None,
   4102            Type::new(Void),
   4103            vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4104        );
   4105        declare_function(
   4106            state,
   4107            "swgl_commitTextureLinearColorRGBA8",
   4108            None,
   4109            Type::new(Void),
   4110            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
   4111        );
   4112        declare_function(
   4113            state,
   4114            "swgl_commitTextureLinearColorRGBA8",
   4115            None,
   4116            Type::new(Void),
   4117            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
   4118        );
   4119        declare_function(
   4120            state,
   4121            "swgl_commitTextureLinearColorR8",
   4122            None,
   4123            Type::new(Void),
   4124            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
   4125        );
   4126        declare_function(
   4127            state,
   4128            "swgl_commitTextureLinearColorR8ToRGBA8",
   4129            None,
   4130            Type::new(Void),
   4131            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
   4132        );
   4133 
   4134        declare_function(
   4135            state,
   4136            "swgl_commitTextureLinearRepeatRGBA8",
   4137            None,
   4138            Type::new(Void),
   4139            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
   4140                 Type::new(Vec4), Type::new(Vec4)],
   4141        );
   4142        declare_function(
   4143            state,
   4144            "swgl_commitTextureLinearRepeatColorRGBA8",
   4145            None,
   4146            Type::new(Void),
   4147            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
   4148                 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
   4149        );
   4150 
   4151        declare_function(
   4152            state,
   4153            "swgl_commitTextureNearestRGBA8",
   4154            None,
   4155            Type::new(Void),
   4156            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4157        );
   4158        declare_function(
   4159            state,
   4160            "swgl_commitTextureNearestColorRGBA8",
   4161            None,
   4162            Type::new(Void),
   4163            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
   4164        );
   4165        declare_function(
   4166            state,
   4167            "swgl_commitTextureNearestRepeatRGBA8",
   4168            None,
   4169            Type::new(Void),
   4170            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
   4171                 Type::new(Vec4), Type::new(Vec4)],
   4172        );
   4173        declare_function(
   4174            state,
   4175            "swgl_commitTextureNearestRepeatColorRGBA8",
   4176            None,
   4177            Type::new(Void),
   4178            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
   4179                 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
   4180        );
   4181 
   4182        declare_function(
   4183            state,
   4184            "swgl_commitTextureRGBA8",
   4185            None,
   4186            Type::new(Void),
   4187            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
   4188        );
   4189        declare_function(
   4190            state,
   4191            "swgl_commitTextureColorRGBA8",
   4192            None,
   4193            Type::new(Void),
   4194            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
   4195        );
   4196        declare_function(
   4197            state,
   4198            "swgl_commitTextureRepeatRGBA8",
   4199            None,
   4200            Type::new(Void),
   4201            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
   4202                 Type::new(Vec4), Type::new(Vec4)],
   4203        );
   4204        declare_function(
   4205            state,
   4206            "swgl_commitTextureRepeatColorRGBA8",
   4207            None,
   4208            Type::new(Void),
   4209            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
   4210                 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
   4211        );
   4212 
   4213        declare_function(
   4214            state,
   4215            "swgl_commitGaussianBlurRGBA8",
   4216            None,
   4217            Type::new(Void),
   4218            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
   4219                 Type::new(Int), Type::new(Vec2)],
   4220        );
   4221        declare_function(
   4222            state,
   4223            "swgl_commitGaussianBlurR8",
   4224            None,
   4225            Type::new(Void),
   4226            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
   4227                 Type::new(Int), Type::new(Vec2)],
   4228        );
   4229        declare_function(
   4230            state,
   4231            "swgl_commitTextureLinearYUV",
   4232            None,
   4233            Type::new(Void),
   4234            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4235                 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
   4236        );
   4237        declare_function(
   4238            state,
   4239            "swgl_commitTextureLinearYUV",
   4240            None,
   4241            Type::new(Void),
   4242            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4243                 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4244                 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
   4245        );
   4246        declare_function(
   4247            state,
   4248            "swgl_commitTextureLinearYUV",
   4249            None,
   4250            Type::new(Void),
   4251            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4252                 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4253                 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4254                 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
   4255        );
   4256        declare_function(
   4257            state,
   4258            "swgl_commitTextureLinearColorYUV",
   4259            None,
   4260            Type::new(Void),
   4261            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4262                 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
   4263                 Type::new(Float)],
   4264        );
   4265        declare_function(
   4266            state,
   4267            "swgl_commitTextureLinearColorYUV",
   4268            None,
   4269            Type::new(Void),
   4270            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4271                 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4272                 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
   4273                 Type::new(Float)],
   4274        );
   4275        declare_function(
   4276            state,
   4277            "swgl_commitTextureLinearColorYUV",
   4278            None,
   4279            Type::new(Void),
   4280            vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4281                 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4282                 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
   4283                 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
   4284                 Type::new(Float)],
   4285        );
   4286    }
   4287 
   4288    TranslationUnit(tu.0.map(state, translate_external_declaration))
   4289 }
   4290 
   4291 fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass {
   4292    match expr.kind {
   4293        ExprKind::Variable(ref i) => {
   4294            *assign = *i;
   4295            match &state.sym(*i).decl {
   4296                SymDecl::Local(_, _, ref run_class) => *run_class,
   4297                SymDecl::Global(_, _, _, ref run_class) => *run_class,
   4298                _ => panic!(),
   4299            }
   4300        }
   4301        ExprKind::IntConst(_)
   4302        | ExprKind::UIntConst(_)
   4303        | ExprKind::BoolConst(_)
   4304        | ExprKind::FloatConst(_)
   4305        | ExprKind::DoubleConst(_) => RunClass::Scalar,
   4306        ExprKind::Unary(_, ref e) => infer_expr(state, e),
   4307        ExprKind::Binary(_, ref l, ref r) => infer_expr(state, l).merge(infer_expr(state, r)),
   4308        ExprKind::Ternary(ref c, ref s, ref e) => infer_expr(state, c)
   4309            .merge(infer_expr(state, s))
   4310            .merge(infer_expr(state, e)),
   4311        ExprKind::Assignment(ref v, _, ref e) => {
   4312            let mut sym = SymRef(!0);
   4313            let run_class = infer_expr_inner(state, v, &mut sym).merge(infer_expr(state, e));
   4314            assert!(sym != SymRef(!0));
   4315            state.merge_run_class(sym, run_class)
   4316        }
   4317        ExprKind::Bracket(ref e, ref indx) => {
   4318            indx.iter().fold(
   4319                infer_expr_inner(state, e, assign),
   4320                |run_class, indx| run_class.merge(infer_expr(state, indx)),
   4321            )
   4322        }
   4323        ExprKind::FunCall(ref fun, ref args) => {
   4324            let arg_classes: Vec<(RunClass, SymRef)> = args
   4325                .iter()
   4326                .map(|e| {
   4327                    let mut assign = SymRef(!0);
   4328                    let run_class = infer_expr_inner(state, e, &mut assign);
   4329                    (run_class, assign)
   4330                })
   4331                .collect();
   4332            let run_class = if args.is_empty() {
   4333                RunClass::Scalar
   4334            } else {
   4335                arg_classes
   4336                    .iter()
   4337                    .fold(RunClass::Unknown, |x, &(y, _)| x.merge(y))
   4338            };
   4339            match fun {
   4340                FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl {
   4341                    SymDecl::NativeFunction(_, _, ref ret_class) => {
   4342                        if *ret_class != RunClass::Unknown {
   4343                            *ret_class
   4344                        } else {
   4345                            run_class
   4346                        }
   4347                    }
   4348                    SymDecl::UserFunction(ref fd, ref run_class) => {
   4349                        for (&(mut arg_class, assign), param) in
   4350                            arg_classes.iter().zip(fd.prototype.parameters.iter())
   4351                        {
   4352                            if let FunctionParameterDeclaration::Named(Some(qual), p) = param {
   4353                                match qual {
   4354                                    ParameterQualifier::InOut | ParameterQualifier::Out => {
   4355                                        if let SymDecl::Local(_, _, param_class) =
   4356                                            &state.sym(p.sym).decl
   4357                                        {
   4358                                            match param_class {
   4359                                                RunClass::Unknown | RunClass::Vector => {
   4360                                                    arg_class = RunClass::Vector;
   4361                                                }
   4362                                                RunClass::Dependent(mask) => {
   4363                                                    for i in 0 .. 31 {
   4364                                                        if (mask & (1 << i)) != 0 {
   4365                                                            arg_class =
   4366                                                                arg_class.merge(arg_classes[i].0);
   4367                                                        }
   4368                                                    }
   4369                                                }
   4370                                                RunClass::Scalar => {}
   4371                                            }
   4372                                        }
   4373                                        assert!(assign != SymRef(!0));
   4374                                        state.merge_run_class(assign, arg_class);
   4375                                    }
   4376                                    _ => {}
   4377                                }
   4378                            }
   4379                        }
   4380                        if fd.prototype.ty.kind == TypeKind::Void {
   4381                            RunClass::Scalar
   4382                        } else {
   4383                            match *run_class {
   4384                                RunClass::Unknown | RunClass::Vector => RunClass::Vector,
   4385                                RunClass::Dependent(mask) => {
   4386                                    let mut ret_class = RunClass::Unknown;
   4387                                    for i in 0 .. 31 {
   4388                                        if (mask & (1 << i)) != 0 {
   4389                                            ret_class = ret_class.merge(arg_classes[i].0);
   4390                                        }
   4391                                    }
   4392                                    ret_class
   4393                                }
   4394                                RunClass::Scalar => RunClass::Scalar,
   4395                            }
   4396                        }
   4397                    }
   4398                    SymDecl::Struct(..) => run_class,
   4399                    _ => panic!(),
   4400                },
   4401                FunIdentifier::Constructor(..) => run_class,
   4402            }
   4403        }
   4404        ExprKind::Dot(ref e, _) => infer_expr_inner(state, e, assign),
   4405        ExprKind::SwizzleSelector(ref e, _) => infer_expr_inner(state, e, assign),
   4406        ExprKind::PostInc(ref e) => infer_expr_inner(state, e, assign),
   4407        ExprKind::PostDec(ref e) => infer_expr_inner(state, e, assign),
   4408        ExprKind::Comma(ref a, ref b) => {
   4409            infer_expr(state, a);
   4410            infer_expr(state, b)
   4411        }
   4412        ExprKind::Cond(_, ref e) => infer_expr(state, e),
   4413        ExprKind::CondMask => RunClass::Vector,
   4414    }
   4415 }
   4416 
   4417 fn infer_expr(state: &mut State, expr: &Expr) -> RunClass {
   4418    infer_expr_inner(state, expr, &mut SymRef(!0))
   4419 }
   4420 
   4421 fn infer_condition(state: &mut State, c: &Condition) {
   4422    match *c {
   4423        Condition::Expr(ref e) => {
   4424            infer_expr(state, e);
   4425        }
   4426    }
   4427 }
   4428 
   4429 fn infer_iteration_statement(state: &mut State, ist: &IterationStatement) {
   4430    let changed = state.run_class_changed.replace(true);
   4431    match *ist {
   4432        IterationStatement::While(ref cond, ref body) => {
   4433            while state.run_class_changed.replace(false) {
   4434                infer_condition(state, cond);
   4435                infer_statement(state, body);
   4436            }
   4437        }
   4438        IterationStatement::DoWhile(ref body, ref cond) => {
   4439            while state.run_class_changed.replace(false) {
   4440                infer_statement(state, body);
   4441                infer_expr(state, cond);
   4442            }
   4443        }
   4444        IterationStatement::For(ref init, ref rest, ref body) => {
   4445            match *init {
   4446                ForInitStatement::Expression(ref expr) => {
   4447                    if let Some(ref e) = *expr {
   4448                        infer_expr(state, e);
   4449                    }
   4450                }
   4451                ForInitStatement::Declaration(ref d) => {
   4452                    infer_declaration(state, d);
   4453                }
   4454            }
   4455            while state.run_class_changed.replace(false) {
   4456                if let Some(ref cond) = rest.condition {
   4457                    infer_condition(state, cond);
   4458                }
   4459                if let Some(ref e) = rest.post_expr {
   4460                    infer_expr(state, e);
   4461                }
   4462                infer_statement(state, body);
   4463            }
   4464        }
   4465    }
   4466    state.run_class_changed.set(changed);
   4467 }
   4468 
   4469 fn infer_selection_statement(state: &mut State, sst: &SelectionStatement) {
   4470    let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.cond));
   4471    mem::swap(&mut state.branch_run_class, &mut branch_run_class);
   4472    let branch_declaration = state.branch_declaration;
   4473    state.branch_declaration = state.last_declaration;
   4474    infer_statement(state, &sst.body);
   4475    if let Some(ref else_st) = sst.else_stmt {
   4476        infer_statement(state, else_st);
   4477    }
   4478    state.branch_run_class = branch_run_class;
   4479    state.branch_declaration = branch_declaration;
   4480 }
   4481 
   4482 fn infer_expression_statement(state: &mut State, est: &ExprStatement) {
   4483    if let Some(ref e) = *est {
   4484        infer_expr(state, e);
   4485    }
   4486 }
   4487 
   4488 fn infer_switch_statement(state: &mut State, sst: &SwitchStatement) {
   4489    let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.head));
   4490    mem::swap(&mut state.branch_run_class, &mut branch_run_class);
   4491    let branch_declaration = state.branch_declaration;
   4492    state.branch_declaration = state.last_declaration;
   4493    for case in &sst.cases {
   4494        for st in &case.stmts {
   4495            infer_statement(state, st);
   4496        }
   4497    }
   4498    state.branch_run_class = branch_run_class;
   4499    state.branch_declaration = branch_declaration;
   4500 }
   4501 
   4502 fn infer_jump_statement(state: &mut State, j: &JumpStatement) {
   4503    match *j {
   4504        JumpStatement::Continue => {}
   4505        JumpStatement::Break => {}
   4506        JumpStatement::Discard => {}
   4507        JumpStatement::Return(ref e) => {
   4508            if let Some(e) = e {
   4509                let run_class = infer_expr(state, e);
   4510                state.return_run_class(run_class);
   4511            }
   4512        }
   4513    }
   4514 }
   4515 
   4516 fn infer_initializer(state: &mut State, i: &Initializer) -> RunClass {
   4517    match *i {
   4518        Initializer::Simple(ref e) => infer_expr(state, e),
   4519        Initializer::List(ref list) => {
   4520            let mut run_class = RunClass::Unknown;
   4521            for ini in list.0.iter() {
   4522                run_class = run_class.merge(infer_initializer(state, ini));
   4523            }
   4524            run_class
   4525        }
   4526    }
   4527 }
   4528 
   4529 fn infer_declaration(state: &mut State, d: &Declaration) {
   4530    match *d {
   4531        Declaration::FunctionPrototype(..) => {}
   4532        Declaration::InitDeclaratorList(ref list) => {
   4533            state.last_declaration = list.head.name;
   4534 
   4535            let mut run_class = RunClass::Unknown;
   4536            for decl in &list.tail {
   4537                if let Some(ref initializer) = decl.initializer {
   4538                    run_class = run_class.merge(infer_initializer(state, initializer));
   4539                }
   4540            }
   4541            if let Some(ref initializer) = list.head.initializer {
   4542                run_class = run_class.merge(infer_initializer(state, initializer));
   4543                state.merge_run_class(list.head.name, run_class);
   4544            }
   4545        }
   4546        Declaration::Precision(..) => {}
   4547        Declaration::Block(..) => {}
   4548        Declaration::Global(..) => {}
   4549        Declaration::StructDefinition(..) => {}
   4550    }
   4551 }
   4552 
   4553 fn infer_simple_statement(state: &mut State, sst: &SimpleStatement) {
   4554    match *sst {
   4555        SimpleStatement::Declaration(ref d) => infer_declaration(state, d),
   4556        SimpleStatement::Expression(ref e) => infer_expression_statement(state, e),
   4557        SimpleStatement::Selection(ref s) => infer_selection_statement(state, s),
   4558        SimpleStatement::Switch(ref s) => infer_switch_statement(state, s),
   4559        SimpleStatement::Iteration(ref i) => infer_iteration_statement(state, i),
   4560        SimpleStatement::Jump(ref j) => infer_jump_statement(state, j),
   4561    }
   4562 }
   4563 
   4564 fn infer_compound_statement(state: &mut State, cst: &CompoundStatement) {
   4565    for st in &cst.statement_list {
   4566        infer_statement(state, st);
   4567    }
   4568 }
   4569 
   4570 fn infer_statement(state: &mut State, st: &Statement) {
   4571    match *st {
   4572        Statement::Compound(ref cst) => infer_compound_statement(state, cst),
   4573        Statement::Simple(ref sst) => infer_simple_statement(state, sst),
   4574    }
   4575 }
   4576 
   4577 fn infer_function_definition(state: &mut State, fd: &FunctionDefinition) {
   4578    state.in_function = Some(state.lookup(fd.prototype.name.as_str()).unwrap());
   4579 
   4580    state.run_class_changed.set(true);
   4581    while state.run_class_changed.replace(false) {
   4582        for st in &fd.body.statement_list {
   4583            infer_statement(state, st);
   4584        }
   4585    }
   4586 
   4587    state.in_function = None;
   4588 }
   4589 
   4590 fn infer_external_declaration(state: &mut State, ed: &ExternalDeclaration) {
   4591    match *ed {
   4592        ExternalDeclaration::Preprocessor(_) => {}
   4593        ExternalDeclaration::FunctionDefinition(ref fd) => infer_function_definition(state, fd),
   4594        ExternalDeclaration::Declaration(_) => {}
   4595    }
   4596 }
   4597 
   4598 pub fn infer_run_class(state: &mut State, tu: &TranslationUnit) {
   4599    for ed in &(tu.0).0 {
   4600        infer_external_declaration(state, ed);
   4601    }
   4602 }