tor-browser

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

Compiler.cpp (63763B)


      1 //
      2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #include "compiler/translator/Compiler.h"
      8 
      9 #include <sstream>
     10 
     11 #include "angle_gl.h"
     12 #include "common/utilities.h"
     13 #include "compiler/translator/CallDAG.h"
     14 #include "compiler/translator/CollectVariables.h"
     15 #include "compiler/translator/Initialize.h"
     16 #include "compiler/translator/IsASTDepthBelowLimit.h"
     17 #include "compiler/translator/OutputTree.h"
     18 #include "compiler/translator/ParseContext.h"
     19 #include "compiler/translator/ValidateBarrierFunctionCall.h"
     20 #include "compiler/translator/ValidateClipCullDistance.h"
     21 #include "compiler/translator/ValidateLimitations.h"
     22 #include "compiler/translator/ValidateMaxParameters.h"
     23 #include "compiler/translator/ValidateOutputs.h"
     24 #include "compiler/translator/ValidateTypeSizeLimitations.h"
     25 #include "compiler/translator/ValidateVaryingLocations.h"
     26 #include "compiler/translator/VariablePacker.h"
     27 #include "compiler/translator/tree_ops/ClampIndirectIndices.h"
     28 #include "compiler/translator/tree_ops/ClampPointSize.h"
     29 #include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
     30 #include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
     31 #include "compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h"
     32 #include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
     33 #include "compiler/translator/tree_ops/FoldExpressions.h"
     34 #include "compiler/translator/tree_ops/ForcePrecisionQualifier.h"
     35 #include "compiler/translator/tree_ops/InitializeVariables.h"
     36 #include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
     37 #include "compiler/translator/tree_ops/PruneEmptyCases.h"
     38 #include "compiler/translator/tree_ops/PruneNoOps.h"
     39 #include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
     40 #include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
     41 #include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
     42 #include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
     43 #include "compiler/translator/tree_ops/RewritePixelLocalStorage.h"
     44 #include "compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h"
     45 #include "compiler/translator/tree_ops/SeparateDeclarations.h"
     46 #include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
     47 #include "compiler/translator/tree_ops/SplitSequenceOperator.h"
     48 #include "compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h"
     49 #include "compiler/translator/tree_ops/apple/RewriteDoWhile.h"
     50 #include "compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h"
     51 #include "compiler/translator/tree_ops/gl/ClampFragDepth.h"
     52 #include "compiler/translator/tree_ops/gl/RegenerateStructNames.h"
     53 #include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h"
     54 #include "compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h"
     55 #include "compiler/translator/tree_util/BuiltIn.h"
     56 #include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
     57 #include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
     58 #include "compiler/translator/util.h"
     59 
     60 // #define ANGLE_FUZZER_CORPUS_OUTPUT_DIR "corpus/"
     61 
     62 #if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
     63 #    include "common/hash_utils.h"
     64 #    include "common/mathutil.h"
     65 #endif
     66 
     67 namespace sh
     68 {
     69 
     70 namespace
     71 {
     72 // Helper that returns if a top-level node is unused.  If it's a function, the function prototype is
     73 // returned as well.
     74 bool IsTopLevelNodeUnusedFunction(const CallDAG &callDag,
     75                                  const std::vector<TFunctionMetadata> &metadata,
     76                                  TIntermNode *node,
     77                                  const TFunction **functionOut)
     78 {
     79    const TIntermFunctionPrototype *asFunctionPrototype   = node->getAsFunctionPrototypeNode();
     80    const TIntermFunctionDefinition *asFunctionDefinition = node->getAsFunctionDefinition();
     81 
     82    *functionOut = nullptr;
     83 
     84    if (asFunctionDefinition)
     85    {
     86        *functionOut = asFunctionDefinition->getFunction();
     87    }
     88    else if (asFunctionPrototype)
     89    {
     90        *functionOut = asFunctionPrototype->getFunction();
     91    }
     92    if (*functionOut == nullptr)
     93    {
     94        return false;
     95    }
     96 
     97    size_t callDagIndex = callDag.findIndex((*functionOut)->uniqueId());
     98    if (callDagIndex == CallDAG::InvalidIndex)
     99    {
    100        // This happens only for unimplemented prototypes which are thus unused
    101        ASSERT(asFunctionPrototype);
    102        return true;
    103    }
    104 
    105    ASSERT(callDagIndex < metadata.size());
    106    return !metadata[callDagIndex].used;
    107 }
    108 
    109 #if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
    110 void DumpFuzzerCase(char const *const *shaderStrings,
    111                    size_t numStrings,
    112                    uint32_t type,
    113                    uint32_t spec,
    114                    uint32_t output,
    115                    const ShCompileOptions &options)
    116 {
    117    ShaderDumpHeader header{};
    118    header.type   = type;
    119    header.spec   = spec;
    120    header.output = output;
    121    memcpy(&header.basicCompileOptions, &options, offsetof(ShCompileOptions, metal));
    122    static_assert(offsetof(ShCompileOptions, metal) <= sizeof(header.basicCompileOptions));
    123    memcpy(&header.metalCompileOptions, &options.metal, sizeof(options.metal));
    124    static_assert(sizeof(options.metal) <= sizeof(header.metalCompileOptions));
    125    memcpy(&header.plsCompileOptions, &options.pls, sizeof(options.pls));
    126    static_assert(sizeof(options.pls) <= sizeof(header.plsCompileOptions));
    127    size_t contentsLength = sizeof(header) + 1;  // Extra: header + nul terminator.
    128    for (size_t i = 0; i < numStrings; i++)
    129    {
    130        contentsLength += strlen(shaderStrings[i]);
    131    }
    132    std::vector<uint8_t> contents(rx::roundUp<size_t>(contentsLength, 4), 0);
    133    memcpy(&contents[0], &header, sizeof(header));
    134    uint8_t *data = &contents[sizeof(header)];
    135    for (size_t i = 0; i < numStrings; i++)
    136    {
    137        auto length = strlen(shaderStrings[i]);
    138        memcpy(data, shaderStrings[i], length);
    139        data += length;
    140    }
    141    auto hash = angle::ComputeGenericHash(contents.data(), contents.size());
    142 
    143    std::ostringstream o = sh::InitializeStream<std::ostringstream>();
    144    o << ANGLE_FUZZER_CORPUS_OUTPUT_DIR << std::hex << std::setw(16) << std::setfill('0') << hash
    145      << ".sample";
    146    std::string s = o.str();
    147 
    148    // Must match the input format of the fuzzer
    149    FILE *f = fopen(s.c_str(), "w");
    150    fwrite(contents.data(), sizeof(char), contentsLength, f);
    151    fclose(f);
    152 }
    153 #endif  // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
    154 }  // anonymous namespace
    155 
    156 bool IsGLSL130OrNewer(ShShaderOutput output)
    157 {
    158    return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
    159            output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
    160            output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT ||
    161            output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
    162            output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
    163 }
    164 
    165 bool IsGLSL420OrNewer(ShShaderOutput output)
    166 {
    167    return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
    168            output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
    169 }
    170 
    171 bool IsGLSL410OrOlder(ShShaderOutput output)
    172 {
    173    return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
    174            output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
    175            output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
    176 }
    177 
    178 bool RemoveInvariant(sh::GLenum shaderType,
    179                     int shaderVersion,
    180                     ShShaderOutput outputType,
    181                     const ShCompileOptions &compileOptions)
    182 {
    183    if (shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
    184        return true;
    185 
    186    if (compileOptions.removeInvariantAndCentroidForESSL3 && shaderVersion >= 300 &&
    187        shaderType == GL_VERTEX_SHADER)
    188        return true;
    189 
    190    return false;
    191 }
    192 
    193 size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
    194 {
    195    // WebGL defines a max token length of 256, while ES2 leaves max token
    196    // size undefined. ES3 defines a max size of 1024 characters.
    197    switch (spec)
    198    {
    199        case SH_WEBGL_SPEC:
    200            return 256;
    201        default:
    202            return 1024;
    203    }
    204 }
    205 
    206 int GetMaxUniformVectorsForShaderType(GLenum shaderType, const ShBuiltInResources &resources)
    207 {
    208    switch (shaderType)
    209    {
    210        case GL_VERTEX_SHADER:
    211            return resources.MaxVertexUniformVectors;
    212        case GL_FRAGMENT_SHADER:
    213            return resources.MaxFragmentUniformVectors;
    214 
    215        // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting
    216        case GL_COMPUTE_SHADER:
    217            return resources.MaxComputeUniformComponents / 4;
    218        case GL_GEOMETRY_SHADER_EXT:
    219            return resources.MaxGeometryUniformComponents / 4;
    220        default:
    221            UNREACHABLE();
    222            return -1;
    223    }
    224 }
    225 
    226 namespace
    227 {
    228 
    229 class [[nodiscard]] TScopedPoolAllocator
    230 {
    231  public:
    232    TScopedPoolAllocator(angle::PoolAllocator *allocator) : mAllocator(allocator)
    233    {
    234        mAllocator->push();
    235        SetGlobalPoolAllocator(mAllocator);
    236    }
    237    ~TScopedPoolAllocator()
    238    {
    239        SetGlobalPoolAllocator(nullptr);
    240        mAllocator->pop();
    241    }
    242 
    243  private:
    244    angle::PoolAllocator *mAllocator;
    245 };
    246 
    247 class [[nodiscard]] TScopedSymbolTableLevel
    248 {
    249  public:
    250    TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table)
    251    {
    252        ASSERT(mTable->isEmpty());
    253        mTable->push();
    254    }
    255    ~TScopedSymbolTableLevel()
    256    {
    257        while (!mTable->isEmpty())
    258            mTable->pop();
    259    }
    260 
    261  private:
    262    TSymbolTable *mTable;
    263 };
    264 
    265 int GetMaxShaderVersionForSpec(ShShaderSpec spec)
    266 {
    267    switch (spec)
    268    {
    269        case SH_GLES2_SPEC:
    270        case SH_WEBGL_SPEC:
    271            return 100;
    272        case SH_GLES3_SPEC:
    273        case SH_WEBGL2_SPEC:
    274            return 300;
    275        case SH_GLES3_1_SPEC:
    276        case SH_WEBGL3_SPEC:
    277            return 310;
    278        case SH_GLES3_2_SPEC:
    279            return 320;
    280        case SH_GL_CORE_SPEC:
    281        case SH_GL_COMPATIBILITY_SPEC:
    282            return 460;
    283        default:
    284            UNREACHABLE();
    285            return 0;
    286    }
    287 }
    288 
    289 bool ValidateFragColorAndFragData(GLenum shaderType,
    290                                  int shaderVersion,
    291                                  const TSymbolTable &symbolTable,
    292                                  TDiagnostics *diagnostics)
    293 {
    294    if (shaderVersion > 100 || shaderType != GL_FRAGMENT_SHADER)
    295    {
    296        return true;
    297    }
    298 
    299    bool usesFragColor = false;
    300    bool usesFragData  = false;
    301    // This validation is a bit stricter than the spec - it's only an error to write to
    302    // both FragData and FragColor. But because it's better not to have reads from undefined
    303    // variables, we always return an error if they are both referenced, rather than only if they
    304    // are written.
    305    if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_FragColor()) ||
    306        symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()))
    307    {
    308        usesFragColor = true;
    309    }
    310    // Extension variables may not always be initialized (saves some time at symbol table init).
    311    bool secondaryFragDataUsed =
    312        symbolTable.gl_SecondaryFragDataEXT() != nullptr &&
    313        symbolTable.isStaticallyUsed(*symbolTable.gl_SecondaryFragDataEXT());
    314    if (symbolTable.isStaticallyUsed(*symbolTable.gl_FragData()) || secondaryFragDataUsed)
    315    {
    316        usesFragData = true;
    317    }
    318    if (usesFragColor && usesFragData)
    319    {
    320        const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
    321        if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()) ||
    322            secondaryFragDataUsed)
    323        {
    324            errorMessage =
    325                "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
    326                " and (gl_FragColor, gl_SecondaryFragColorEXT)";
    327        }
    328        diagnostics->globalError(errorMessage);
    329        return false;
    330    }
    331    return true;
    332 }
    333 
    334 }  // namespace
    335 
    336 TShHandleBase::TShHandleBase()
    337 {
    338    allocator.push();
    339    SetGlobalPoolAllocator(&allocator);
    340 }
    341 
    342 TShHandleBase::~TShHandleBase()
    343 {
    344    SetGlobalPoolAllocator(nullptr);
    345    allocator.popAll();
    346 }
    347 
    348 TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
    349    : mVariablesCollected(false),
    350      mGLPositionInitialized(false),
    351      mShaderType(type),
    352      mShaderSpec(spec),
    353      mOutputType(output),
    354      mBuiltInFunctionEmulator(),
    355      mDiagnostics(mInfoSink.info),
    356      mSourcePath(nullptr),
    357      mComputeShaderLocalSizeDeclared(false),
    358      mComputeShaderLocalSize(1),
    359      mGeometryShaderMaxVertices(-1),
    360      mGeometryShaderInvocations(0),
    361      mGeometryShaderInputPrimitiveType(EptUndefined),
    362      mGeometryShaderOutputPrimitiveType(EptUndefined),
    363      mTessControlShaderOutputVertices(0),
    364      mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
    365      mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
    366      mTessEvaluationShaderInputOrderingType(EtetUndefined),
    367      mTessEvaluationShaderInputPointType(EtetUndefined),
    368      mHasAnyPreciseType(false),
    369      mAdvancedBlendEquations(0),
    370      mHasPixelLocalStorageUniforms(false),
    371      mCompileOptions{}
    372 {}
    373 
    374 TCompiler::~TCompiler() {}
    375 
    376 bool TCompiler::isHighPrecisionSupported() const
    377 {
    378    return mShaderVersion > 100 || mShaderType != GL_FRAGMENT_SHADER ||
    379           mResources.FragmentPrecisionHigh == 1;
    380 }
    381 
    382 bool TCompiler::shouldRunLoopAndIndexingValidation(const ShCompileOptions &compileOptions) const
    383 {
    384    // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API,
    385    // validate loop and indexing as well (to verify that the shader only uses minimal functionality
    386    // of ESSL 1.00 as in Appendix A of the spec).
    387    return (IsWebGLBasedSpec(mShaderSpec) && mShaderVersion == 100) ||
    388           compileOptions.validateLoopIndexing;
    389 }
    390 
    391 bool TCompiler::shouldLimitTypeSizes() const
    392 {
    393    // WebGL shaders limit the size of variables' types in shaders,
    394    // including arrays, structs and interface blocks.
    395    return IsWebGLBasedSpec(mShaderSpec);
    396 }
    397 
    398 bool TCompiler::Init(const ShBuiltInResources &resources)
    399 {
    400    SetGlobalPoolAllocator(&allocator);
    401 
    402    // Generate built-in symbol table.
    403    if (!initBuiltInSymbolTable(resources))
    404        return false;
    405 
    406    mResources = resources;
    407    setResourceString();
    408 
    409    InitExtensionBehavior(resources, mExtensionBehavior);
    410    return true;
    411 }
    412 
    413 TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
    414                                               size_t numStrings,
    415                                               const ShCompileOptions &compileOptions)
    416 {
    417    return compileTreeImpl(shaderStrings, numStrings, compileOptions);
    418 }
    419 
    420 TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
    421                                         size_t numStrings,
    422                                         const ShCompileOptions &compileOptions)
    423 {
    424    // Remember the compile options for helper functions such as validateAST.
    425    mCompileOptions = compileOptions;
    426 
    427    clearResults();
    428 
    429    ASSERT(numStrings > 0);
    430    ASSERT(GetGlobalPoolAllocator());
    431 
    432    // Reset the extension behavior for each compilation unit.
    433    ResetExtensionBehavior(mResources, mExtensionBehavior, compileOptions);
    434 
    435    // If gl_DrawID is not supported, remove it from the available extensions
    436    // Currently we only allow emulation of gl_DrawID
    437    const bool glDrawIDSupported = compileOptions.emulateGLDrawID;
    438    if (!glDrawIDSupported)
    439    {
    440        auto it = mExtensionBehavior.find(TExtension::ANGLE_multi_draw);
    441        if (it != mExtensionBehavior.end())
    442        {
    443            mExtensionBehavior.erase(it);
    444        }
    445    }
    446 
    447    const bool glBaseVertexBaseInstanceSupported = compileOptions.emulateGLBaseVertexBaseInstance;
    448    if (!glBaseVertexBaseInstanceSupported)
    449    {
    450        auto it =
    451            mExtensionBehavior.find(TExtension::ANGLE_base_vertex_base_instance_shader_builtin);
    452        if (it != mExtensionBehavior.end())
    453        {
    454            mExtensionBehavior.erase(it);
    455        }
    456    }
    457 
    458    // First string is path of source file if flag is set. The actual source follows.
    459    size_t firstSource = 0;
    460    if (compileOptions.sourcePath)
    461    {
    462        mSourcePath = shaderStrings[0];
    463        ++firstSource;
    464    }
    465 
    466    TParseContext parseContext(mSymbolTable, mExtensionBehavior, mShaderType, mShaderSpec,
    467                               compileOptions, !IsDesktopGLSpec(mShaderSpec), &mDiagnostics,
    468                               getResources(), getOutputType());
    469 
    470    parseContext.setFragmentPrecisionHighOnESSL1(mResources.FragmentPrecisionHigh == 1);
    471 
    472    // We preserve symbols at the built-in level from compile-to-compile.
    473    // Start pushing the user-defined symbols at global level.
    474    TScopedSymbolTableLevel globalLevel(&mSymbolTable);
    475    ASSERT(mSymbolTable.atGlobalLevel());
    476 
    477    // Parse shader.
    478    if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
    479                       &parseContext) != 0)
    480    {
    481        return nullptr;
    482    }
    483 
    484    if (!postParseChecks(parseContext))
    485    {
    486        return nullptr;
    487    }
    488 
    489    setASTMetadata(parseContext);
    490 
    491    if (!checkShaderVersion(&parseContext))
    492    {
    493        return nullptr;
    494    }
    495 
    496    TIntermBlock *root = parseContext.getTreeRoot();
    497    if (!checkAndSimplifyAST(root, parseContext, compileOptions))
    498    {
    499        return nullptr;
    500    }
    501 
    502    return root;
    503 }
    504 
    505 bool TCompiler::checkShaderVersion(TParseContext *parseContext)
    506 {
    507    if (GetMaxShaderVersionForSpec(mShaderSpec) < mShaderVersion)
    508    {
    509        mDiagnostics.globalError("unsupported shader version");
    510        return false;
    511    }
    512 
    513    ASSERT(parseContext);
    514    switch (mShaderType)
    515    {
    516        case GL_COMPUTE_SHADER:
    517            if (mShaderVersion < 310)
    518            {
    519                mDiagnostics.globalError("Compute shader is not supported in this shader version.");
    520                return false;
    521            }
    522            break;
    523 
    524        case GL_GEOMETRY_SHADER_EXT:
    525            if (mShaderVersion < 310)
    526            {
    527                mDiagnostics.globalError(
    528                    "Geometry shader is not supported in this shader version.");
    529                return false;
    530            }
    531            else if (mShaderVersion == 310)
    532            {
    533                if (!parseContext->checkCanUseOneOfExtensions(
    534                        sh::TSourceLoc(),
    535                        std::array<TExtension, 2u>{
    536                            {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}))
    537                {
    538                    return false;
    539                }
    540            }
    541            break;
    542 
    543        case GL_TESS_CONTROL_SHADER_EXT:
    544        case GL_TESS_EVALUATION_SHADER_EXT:
    545            if (mShaderVersion < 310)
    546            {
    547                mDiagnostics.globalError(
    548                    "Tessellation shaders are not supported in this shader version.");
    549                return false;
    550            }
    551            else if (mShaderVersion == 310)
    552            {
    553                if (!parseContext->checkCanUseExtension(sh::TSourceLoc(),
    554                                                        TExtension::EXT_tessellation_shader))
    555                {
    556                    return false;
    557                }
    558            }
    559            break;
    560 
    561        default:
    562            break;
    563    }
    564 
    565    return true;
    566 }
    567 
    568 void TCompiler::setASTMetadata(const TParseContext &parseContext)
    569 {
    570    mShaderVersion = parseContext.getShaderVersion();
    571 
    572    mPragma = parseContext.pragma();
    573    mSymbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll);
    574 
    575    mEarlyFragmentTestsSpecified = parseContext.isEarlyFragmentTestsSpecified();
    576 
    577    mHasDiscard = parseContext.hasDiscard();
    578 
    579    mEnablesPerSampleShading = parseContext.isSampleQualifierSpecified();
    580 
    581    mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
    582    mComputeShaderLocalSize         = parseContext.getComputeShaderLocalSize();
    583 
    584    mNumViews = parseContext.getNumViews();
    585 
    586    mHasAnyPreciseType = parseContext.hasAnyPreciseType();
    587 
    588    if (mShaderType == GL_FRAGMENT_SHADER)
    589    {
    590        mAdvancedBlendEquations       = parseContext.getAdvancedBlendEquations();
    591        mHasPixelLocalStorageUniforms = !parseContext.pixelLocalStorageBindings().empty();
    592    }
    593    if (mShaderType == GL_GEOMETRY_SHADER_EXT)
    594    {
    595        mGeometryShaderInputPrimitiveType  = parseContext.getGeometryShaderInputPrimitiveType();
    596        mGeometryShaderOutputPrimitiveType = parseContext.getGeometryShaderOutputPrimitiveType();
    597        mGeometryShaderMaxVertices         = parseContext.getGeometryShaderMaxVertices();
    598        mGeometryShaderInvocations         = parseContext.getGeometryShaderInvocations();
    599    }
    600    if (mShaderType == GL_TESS_CONTROL_SHADER_EXT)
    601    {
    602        mTessControlShaderOutputVertices = parseContext.getTessControlShaderOutputVertices();
    603    }
    604    if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT)
    605    {
    606        mTessEvaluationShaderInputPrimitiveType =
    607            parseContext.getTessEvaluationShaderInputPrimitiveType();
    608        mTessEvaluationShaderInputVertexSpacingType =
    609            parseContext.getTessEvaluationShaderInputVertexSpacingType();
    610        mTessEvaluationShaderInputOrderingType =
    611            parseContext.getTessEvaluationShaderInputOrderingType();
    612        mTessEvaluationShaderInputPointType = parseContext.getTessEvaluationShaderInputPointType();
    613    }
    614 }
    615 
    616 unsigned int TCompiler::getSharedMemorySize() const
    617 {
    618    unsigned int sharedMemSize = 0;
    619    for (const sh::ShaderVariable &var : mSharedVariables)
    620    {
    621        sharedMemSize += var.getExternalSize();
    622    }
    623 
    624    return sharedMemSize;
    625 }
    626 
    627 bool TCompiler::validateAST(TIntermNode *root)
    628 {
    629    if (mCompileOptions.validateAST)
    630    {
    631        bool valid = ValidateAST(root, &mDiagnostics, mValidateASTOptions);
    632 
    633 #if defined(ANGLE_ENABLE_ASSERTS)
    634        if (!valid)
    635        {
    636            OutputTree(root, mInfoSink.info);
    637            fprintf(stderr, "AST validation error(s):\n%s\n", mInfoSink.info.c_str());
    638        }
    639 #endif
    640        // In debug, assert validation.  In release, validation errors will be returned back to the
    641        // application as internal ANGLE errors.
    642        ASSERT(valid);
    643 
    644        return valid;
    645    }
    646    return true;
    647 }
    648 
    649 bool TCompiler::disableValidateFunctionCall()
    650 {
    651    bool wasEnabled                          = mValidateASTOptions.validateFunctionCall;
    652    mValidateASTOptions.validateFunctionCall = false;
    653    return wasEnabled;
    654 }
    655 
    656 void TCompiler::restoreValidateFunctionCall(bool enable)
    657 {
    658    ASSERT(!mValidateASTOptions.validateFunctionCall);
    659    mValidateASTOptions.validateFunctionCall = enable;
    660 }
    661 
    662 bool TCompiler::disableValidateVariableReferences()
    663 {
    664    bool wasEnabled                                = mValidateASTOptions.validateVariableReferences;
    665    mValidateASTOptions.validateVariableReferences = false;
    666    return wasEnabled;
    667 }
    668 
    669 void TCompiler::restoreValidateVariableReferences(bool enable)
    670 {
    671    ASSERT(!mValidateASTOptions.validateVariableReferences);
    672    mValidateASTOptions.validateVariableReferences = enable;
    673 }
    674 
    675 void TCompiler::enableValidateNoMoreTransformations()
    676 {
    677    mValidateASTOptions.validateNoMoreTransformations = true;
    678 }
    679 
    680 bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
    681                                    const TParseContext &parseContext,
    682                                    const ShCompileOptions &compileOptions)
    683 {
    684    mValidateASTOptions = {};
    685 
    686    // Desktop GLSL shaders don't have precision, so don't expect them to be specified.
    687    mValidateASTOptions.validatePrecision = !IsDesktopGLSpec(mShaderSpec);
    688 
    689    if (!validateAST(root))
    690    {
    691        return false;
    692    }
    693 
    694    // For now, rewrite pixel local storage before collecting variables or any operations on images.
    695    //
    696    // TODO(anglebug.com/7279):
    697    //   Should this actually run after collecting variables?
    698    //   Do we need more introspection?
    699    //   Do we want to hide rewritten shader image uniforms from glGetActiveUniform?
    700    if (hasPixelLocalStorageUniforms())
    701    {
    702        ASSERT(
    703            IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_shader_pixel_local_storage));
    704        if (!RewritePixelLocalStorage(this, root, getSymbolTable(), compileOptions,
    705                                      getShaderVersion()))
    706        {
    707            mDiagnostics.globalError("internal compiler error translating pixel local storage");
    708            return false;
    709        }
    710    }
    711 
    712    // Disallow expressions deemed too complex.
    713    if (compileOptions.limitExpressionComplexity && !limitExpressionComplexity(root))
    714    {
    715        return false;
    716    }
    717 
    718    if (shouldRunLoopAndIndexingValidation(compileOptions) &&
    719        !ValidateLimitations(root, mShaderType, &mSymbolTable, &mDiagnostics))
    720    {
    721        return false;
    722    }
    723 
    724    if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(mResources, root, &mSymbolTable, &mDiagnostics))
    725    {
    726        return false;
    727    }
    728 
    729    if (!ValidateFragColorAndFragData(mShaderType, mShaderVersion, mSymbolTable, &mDiagnostics))
    730    {
    731        return false;
    732    }
    733 
    734    // Fold expressions that could not be folded before validation that was done as a part of
    735    // parsing.
    736    if (!FoldExpressions(this, root, &mDiagnostics))
    737    {
    738        return false;
    739    }
    740    // Folding should only be able to generate warnings.
    741    ASSERT(mDiagnostics.numErrors() == 0);
    742 
    743    // Validate no barrier() after return before prunning it in |PruneNoOps()| below.
    744    if (mShaderType == GL_TESS_CONTROL_SHADER && !ValidateBarrierFunctionCall(root, &mDiagnostics))
    745    {
    746        return false;
    747    }
    748 
    749    // We prune no-ops to work around driver bugs and to keep AST processing and output simple.
    750    // The following kinds of no-ops are pruned:
    751    //   1. Empty declarations "int;".
    752    //   2. Literal statements: "1.0;". The ESSL output doesn't define a default precision
    753    //      for float, so float literal statements would end up with no precision which is
    754    //      invalid ESSL.
    755    //   3. Any unreachable statement after a discard, return, break or continue.
    756    // After this empty declarations are not allowed in the AST.
    757    if (!PruneNoOps(this, root, &mSymbolTable))
    758    {
    759        return false;
    760    }
    761    mValidateASTOptions.validateNoStatementsAfterBranch = true;
    762 
    763    // We need to generate globals early if we have non constant initializers enabled
    764    bool initializeLocalsAndGlobals =
    765        compileOptions.initializeUninitializedLocals && !IsOutputHLSL(getOutputType());
    766    bool canUseLoopsToInitialize       = !compileOptions.dontUseLoopsToInitializeVariables;
    767    bool highPrecisionSupported        = isHighPrecisionSupported();
    768    bool enableNonConstantInitializers = IsExtensionEnabled(
    769        mExtensionBehavior, TExtension::EXT_shader_non_constant_global_initializers);
    770    // forceDeferGlobalInitializers is needed for MSL
    771    // to convert a non-const global. For example:
    772    //
    773    //    int someGlobal = 123;
    774    //
    775    // to
    776    //
    777    //    int someGlobal;
    778    //    void main() {
    779    //        someGlobal = 123;
    780    //
    781    // This is because MSL doesn't allow statically initialized globals.
    782    bool forceDeferGlobalInitializers = getOutputType() == SH_MSL_METAL_OUTPUT;
    783 
    784    if (enableNonConstantInitializers &&
    785        !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
    786                                 highPrecisionSupported, forceDeferGlobalInitializers,
    787                                 &mSymbolTable))
    788    {
    789        return false;
    790    }
    791 
    792    // Create the function DAG and check there is no recursion
    793    if (!initCallDag(root))
    794    {
    795        return false;
    796    }
    797 
    798    if (compileOptions.limitCallStackDepth && !checkCallDepth())
    799    {
    800        return false;
    801    }
    802 
    803    // Checks which functions are used and if "main" exists
    804    mFunctionMetadata.clear();
    805    mFunctionMetadata.resize(mCallDag.size());
    806    if (!tagUsedFunctions())
    807    {
    808        return false;
    809    }
    810 
    811    if (!pruneUnusedFunctions(root))
    812    {
    813        return false;
    814    }
    815 
    816    if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
    817    {
    818        if (!ReplaceShadowingVariables(this, root, &mSymbolTable))
    819        {
    820            return false;
    821        }
    822    }
    823 
    824    if (mShaderVersion >= 310 && !ValidateVaryingLocations(root, &mDiagnostics, mShaderType))
    825    {
    826        return false;
    827    }
    828 
    829    // anglebug.com/7484: The ESSL spec has a bug with images as function arguments. The recommended
    830    // workaround is to inline functions that accept image arguments.
    831    if (mShaderVersion >= 310 && !MonomorphizeUnsupportedFunctions(
    832                                     this, root, &mSymbolTable, compileOptions,
    833                                     UnsupportedFunctionArgsBitSet{UnsupportedFunctionArgs::Image}))
    834    {
    835        return false;
    836    }
    837 
    838    if (mShaderVersion >= 300 && mShaderType == GL_FRAGMENT_SHADER &&
    839        !ValidateOutputs(root, getExtensionBehavior(), mResources.MaxDrawBuffers, &mDiagnostics))
    840    {
    841        return false;
    842    }
    843 
    844    if (parseContext.isExtensionEnabled(TExtension::EXT_clip_cull_distance))
    845    {
    846        if (!ValidateClipCullDistance(root, &mDiagnostics,
    847                                      mResources.MaxCombinedClipAndCullDistances))
    848        {
    849            return false;
    850        }
    851    }
    852 
    853    // Clamping uniform array bounds needs to happen after validateLimitations pass.
    854    if (compileOptions.clampIndirectArrayBounds)
    855    {
    856        if (!ClampIndirectIndices(this, root, &mSymbolTable))
    857        {
    858            return false;
    859        }
    860    }
    861 
    862    if (compileOptions.initializeBuiltinsForInstancedMultiview &&
    863        (parseContext.isExtensionEnabled(TExtension::OVR_multiview2) ||
    864         parseContext.isExtensionEnabled(TExtension::OVR_multiview)) &&
    865        getShaderType() != GL_COMPUTE_SHADER)
    866    {
    867        if (!DeclareAndInitBuiltinsForInstancedMultiview(
    868                this, root, mNumViews, mShaderType, compileOptions, mOutputType, &mSymbolTable))
    869        {
    870            return false;
    871        }
    872    }
    873 
    874    // This pass might emit short circuits so keep it before the short circuit unfolding
    875    if (compileOptions.rewriteDoWhileLoops)
    876    {
    877        if (!RewriteDoWhile(this, root, &mSymbolTable))
    878        {
    879            return false;
    880        }
    881    }
    882 
    883    if (compileOptions.addAndTrueToLoopCondition)
    884    {
    885        if (!AddAndTrueToLoopCondition(this, root))
    886        {
    887            return false;
    888        }
    889    }
    890 
    891    if (compileOptions.unfoldShortCircuit)
    892    {
    893        if (!UnfoldShortCircuitAST(this, root))
    894        {
    895            return false;
    896        }
    897    }
    898 
    899    if (compileOptions.regenerateStructNames)
    900    {
    901        if (!RegenerateStructNames(this, root, &mSymbolTable))
    902        {
    903            return false;
    904        }
    905    }
    906 
    907    if (mShaderType == GL_VERTEX_SHADER &&
    908        IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw))
    909    {
    910        if (compileOptions.emulateGLDrawID)
    911        {
    912            if (!EmulateGLDrawID(this, root, &mSymbolTable, &mUniforms,
    913                                 shouldCollectVariables(compileOptions)))
    914            {
    915                return false;
    916            }
    917        }
    918    }
    919 
    920    if (mShaderType == GL_VERTEX_SHADER &&
    921        IsExtensionEnabled(mExtensionBehavior,
    922                           TExtension::ANGLE_base_vertex_base_instance_shader_builtin))
    923    {
    924        if (compileOptions.emulateGLBaseVertexBaseInstance)
    925        {
    926            if (!EmulateGLBaseVertexBaseInstance(this, root, &mSymbolTable, &mUniforms,
    927                                                 shouldCollectVariables(compileOptions),
    928                                                 compileOptions.addBaseVertexToVertexID))
    929            {
    930                return false;
    931            }
    932        }
    933    }
    934 
    935    if (mShaderType == GL_FRAGMENT_SHADER && mShaderVersion == 100 && mResources.EXT_draw_buffers &&
    936        mResources.MaxDrawBuffers > 1 &&
    937        IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
    938    {
    939        if (!EmulateGLFragColorBroadcast(this, root, mResources.MaxDrawBuffers, &mOutputVariables,
    940                                         &mSymbolTable, mShaderVersion))
    941        {
    942            return false;
    943        }
    944    }
    945 
    946    int simplifyScalarized = compileOptions.scalarizeVecAndMatConstructorArgs
    947                                 ? IntermNodePatternMatcher::kScalarizedVecOrMatConstructor
    948                                 : 0;
    949 
    950    // Split multi declarations and remove calls to array length().
    951    // Note that SimplifyLoopConditions needs to be run before any other AST transformations
    952    // that may need to generate new statements from loop conditions or loop expressions.
    953    if (!SimplifyLoopConditions(this, root,
    954                                IntermNodePatternMatcher::kMultiDeclaration |
    955                                    IntermNodePatternMatcher::kArrayLengthMethod |
    956                                    simplifyScalarized,
    957                                &getSymbolTable()))
    958    {
    959        return false;
    960    }
    961 
    962    // Note that separate declarations need to be run before other AST transformations that
    963    // generate new statements from expressions.
    964    if (!SeparateDeclarations(this, root, &getSymbolTable()))
    965    {
    966        return false;
    967    }
    968    mValidateASTOptions.validateMultiDeclarations = true;
    969 
    970    if (!SplitSequenceOperator(this, root,
    971                               IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
    972                               &getSymbolTable()))
    973    {
    974        return false;
    975    }
    976 
    977    if (!RemoveArrayLengthMethod(this, root))
    978    {
    979        return false;
    980    }
    981 
    982    if (!RemoveUnreferencedVariables(this, root, &mSymbolTable))
    983    {
    984        return false;
    985    }
    986 
    987    // In case the last case inside a switch statement is a certain type of no-op, GLSL compilers in
    988    // drivers may not accept it. In this case we clean up the dead code from the end of switch
    989    // statements. This is also required because PruneNoOps or RemoveUnreferencedVariables may have
    990    // left switch statements that only contained an empty declaration inside the final case in an
    991    // invalid state. Relies on that PruneNoOps and RemoveUnreferencedVariables have already been
    992    // run.
    993    if (!PruneEmptyCases(this, root))
    994    {
    995        return false;
    996    }
    997 
    998    // Built-in function emulation needs to happen after validateLimitations pass.
    999    GetGlobalPoolAllocator()->lock();
   1000    initBuiltInFunctionEmulator(&mBuiltInFunctionEmulator, compileOptions);
   1001    GetGlobalPoolAllocator()->unlock();
   1002    mBuiltInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
   1003 
   1004    if (compileOptions.scalarizeVecAndMatConstructorArgs)
   1005    {
   1006        if (!ScalarizeVecAndMatConstructorArgs(this, root, &mSymbolTable))
   1007        {
   1008            return false;
   1009        }
   1010    }
   1011 
   1012    if (compileOptions.forceShaderPrecisionHighpToMediump)
   1013    {
   1014        if (!ForceShaderPrecisionToMediump(root, &mSymbolTable, mShaderType))
   1015        {
   1016            return false;
   1017        }
   1018    }
   1019 
   1020    if (shouldCollectVariables(compileOptions))
   1021    {
   1022        ASSERT(!mVariablesCollected);
   1023        CollectVariables(root, &mAttributes, &mOutputVariables, &mUniforms, &mInputVaryings,
   1024                         &mOutputVaryings, &mSharedVariables, &mUniformBlocks,
   1025                         &mShaderStorageBlocks, mResources.HashFunction, &mSymbolTable, mShaderType,
   1026                         mExtensionBehavior, mResources, mTessControlShaderOutputVertices);
   1027        collectInterfaceBlocks();
   1028        mVariablesCollected = true;
   1029        if (compileOptions.useUnusedStandardSharedBlocks)
   1030        {
   1031            if (!useAllMembersInUnusedStandardAndSharedBlocks(root))
   1032            {
   1033                return false;
   1034            }
   1035        }
   1036        if (compileOptions.enforcePackingRestrictions)
   1037        {
   1038            int maxUniformVectors = GetMaxUniformVectorsForShaderType(mShaderType, mResources);
   1039            // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
   1040            // Appendix A, section 7, the shader does not use too many uniforms.
   1041            if (!CheckVariablesInPackingLimits(maxUniformVectors, mUniforms))
   1042            {
   1043                mDiagnostics.globalError("too many uniforms");
   1044                return false;
   1045            }
   1046        }
   1047        bool needInitializeOutputVariables =
   1048            compileOptions.initOutputVariables && mShaderType != GL_COMPUTE_SHADER;
   1049        needInitializeOutputVariables |=
   1050            compileOptions.initFragmentOutputVariables && mShaderType == GL_FRAGMENT_SHADER;
   1051        if (needInitializeOutputVariables)
   1052        {
   1053            if (!initializeOutputVariables(root))
   1054            {
   1055                return false;
   1056            }
   1057        }
   1058    }
   1059 
   1060    // Removing invariant declarations must be done after collecting variables.
   1061    // Otherwise, built-in invariant declarations don't apply.
   1062    if (RemoveInvariant(mShaderType, mShaderVersion, mOutputType, compileOptions))
   1063    {
   1064        if (!RemoveInvariantDeclaration(this, root))
   1065        {
   1066            return false;
   1067        }
   1068    }
   1069 
   1070    // gl_Position is always written in compatibility output mode.
   1071    // It may have been already initialized among other output variables, in that case we don't
   1072    // need to initialize it twice.
   1073    if (mShaderType == GL_VERTEX_SHADER && !mGLPositionInitialized &&
   1074        (compileOptions.initGLPosition || mOutputType == SH_GLSL_COMPATIBILITY_OUTPUT))
   1075    {
   1076        if (!initializeGLPosition(root))
   1077        {
   1078            return false;
   1079        }
   1080        mGLPositionInitialized = true;
   1081    }
   1082 
   1083    if (mShaderType == GL_VERTEX_SHADER && compileOptions.initGLPointSize)
   1084    {
   1085        sh::ShaderVariable var(GL_FLOAT);
   1086        var.name = "gl_PointSize";
   1087        if (!InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion,
   1088                                 mExtensionBehavior, false, false))
   1089        {
   1090            return false;
   1091        }
   1092    }
   1093 
   1094    // DeferGlobalInitializers needs to be run before other AST transformations that generate new
   1095    // statements from expressions. But it's fine to run DeferGlobalInitializers after the above
   1096    // SplitSequenceOperator and RemoveArrayLengthMethod since they only have an effect on the AST
   1097    // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00.
   1098    // Exception: if EXT_shader_non_constant_global_initializers is enabled, we must generate global
   1099    // initializers before we generate the DAG, since initializers may call functions which must not
   1100    // be optimized out
   1101    if (!enableNonConstantInitializers &&
   1102        !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
   1103                                 highPrecisionSupported, forceDeferGlobalInitializers,
   1104                                 &mSymbolTable))
   1105    {
   1106        return false;
   1107    }
   1108 
   1109    if (initializeLocalsAndGlobals)
   1110    {
   1111        // Initialize uninitialized local variables.
   1112        // In some cases initializing can generate extra statements in the parent block, such as
   1113        // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case
   1114        // we need to first simplify loop conditions. We've already separated declarations
   1115        // earlier, which is also required. If we don't follow the Appendix A limitations, loop
   1116        // init statements can declare arrays or nameless structs and have multiple
   1117        // declarations.
   1118 
   1119        if (!shouldRunLoopAndIndexingValidation(compileOptions))
   1120        {
   1121            if (!SimplifyLoopConditions(this, root,
   1122                                        IntermNodePatternMatcher::kArrayDeclaration |
   1123                                            IntermNodePatternMatcher::kNamelessStructDeclaration,
   1124                                        &getSymbolTable()))
   1125            {
   1126                return false;
   1127            }
   1128        }
   1129 
   1130        if (!InitializeUninitializedLocals(this, root, getShaderVersion(), canUseLoopsToInitialize,
   1131                                           highPrecisionSupported, &getSymbolTable()))
   1132        {
   1133            return false;
   1134        }
   1135    }
   1136 
   1137    if (getShaderType() == GL_VERTEX_SHADER && compileOptions.clampPointSize)
   1138    {
   1139        if (!ClampPointSize(this, root, mResources.MaxPointSize, &getSymbolTable()))
   1140        {
   1141            return false;
   1142        }
   1143    }
   1144 
   1145    if (getShaderType() == GL_FRAGMENT_SHADER && compileOptions.clampFragDepth)
   1146    {
   1147        if (!ClampFragDepth(this, root, &getSymbolTable()))
   1148        {
   1149            return false;
   1150        }
   1151    }
   1152 
   1153    if (compileOptions.rewriteRepeatedAssignToSwizzled)
   1154    {
   1155        if (!sh::RewriteRepeatedAssignToSwizzled(this, root))
   1156        {
   1157            return false;
   1158        }
   1159    }
   1160 
   1161    if (compileOptions.removeDynamicIndexingOfSwizzledVector)
   1162    {
   1163        if (!sh::RemoveDynamicIndexingOfSwizzledVector(this, root, &getSymbolTable(), nullptr))
   1164        {
   1165            return false;
   1166        }
   1167    }
   1168 
   1169    return true;
   1170 }
   1171 
   1172 bool TCompiler::postParseChecks(const TParseContext &parseContext)
   1173 {
   1174    std::stringstream errorMessage;
   1175 
   1176    if (parseContext.getTreeRoot() == nullptr)
   1177    {
   1178        errorMessage << "Shader parsing failed (mTreeRoot == nullptr)";
   1179    }
   1180 
   1181    for (TType *type : parseContext.getDeferredArrayTypesToSize())
   1182    {
   1183        errorMessage << "Unsized global array type: " << type->getBasicString();
   1184    }
   1185 
   1186    if (!errorMessage.str().empty())
   1187    {
   1188        mDiagnostics.globalError(errorMessage.str().c_str());
   1189        return false;
   1190    }
   1191 
   1192    return true;
   1193 }
   1194 
   1195 bool TCompiler::compile(const char *const shaderStrings[],
   1196                        size_t numStrings,
   1197                        const ShCompileOptions &compileOptionsIn)
   1198 {
   1199 #if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
   1200    DumpFuzzerCase(shaderStrings, numStrings, mShaderType, mShaderSpec, mOutputType,
   1201                   compileOptionsIn);
   1202 #endif  // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
   1203 
   1204    if (numStrings == 0)
   1205        return true;
   1206 
   1207    ShCompileOptions compileOptions = compileOptionsIn;
   1208 
   1209    // Apply key workarounds.
   1210    if (shouldFlattenPragmaStdglInvariantAll())
   1211    {
   1212        // This should be harmless to do in all cases, but for the moment, do it only conditionally.
   1213        compileOptions.flattenPragmaSTDGLInvariantAll = true;
   1214    }
   1215 
   1216    TScopedPoolAllocator scopedAlloc(&allocator);
   1217    TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
   1218 
   1219    if (root)
   1220    {
   1221        if (compileOptions.intermediateTree)
   1222        {
   1223            OutputTree(root, mInfoSink.info);
   1224        }
   1225 
   1226        if (compileOptions.objectCode)
   1227        {
   1228            PerformanceDiagnostics perfDiagnostics(&mDiagnostics);
   1229            if (!translate(root, compileOptions, &perfDiagnostics))
   1230            {
   1231                return false;
   1232            }
   1233        }
   1234 
   1235        if (mShaderType == GL_VERTEX_SHADER)
   1236        {
   1237            bool lookForDrawID =
   1238                IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw) &&
   1239                compileOptions.emulateGLDrawID;
   1240            bool lookForBaseVertexBaseInstance =
   1241                IsExtensionEnabled(mExtensionBehavior,
   1242                                   TExtension::ANGLE_base_vertex_base_instance_shader_builtin) &&
   1243                compileOptions.emulateGLBaseVertexBaseInstance;
   1244 
   1245            if (lookForDrawID || lookForBaseVertexBaseInstance)
   1246            {
   1247                for (auto &uniform : mUniforms)
   1248                {
   1249                    if (lookForDrawID && uniform.name == "angle_DrawID" &&
   1250                        uniform.mappedName == "angle_DrawID")
   1251                    {
   1252                        uniform.name = "gl_DrawID";
   1253                    }
   1254                    else if (lookForBaseVertexBaseInstance && uniform.name == "angle_BaseVertex" &&
   1255                             uniform.mappedName == "angle_BaseVertex")
   1256                    {
   1257                        uniform.name = "gl_BaseVertex";
   1258                    }
   1259                    else if (lookForBaseVertexBaseInstance &&
   1260                             uniform.name == "angle_BaseInstance" &&
   1261                             uniform.mappedName == "angle_BaseInstance")
   1262                    {
   1263                        uniform.name = "gl_BaseInstance";
   1264                    }
   1265                }
   1266            }
   1267        }
   1268 
   1269        // The IntermNode tree doesn't need to be deleted here, since the
   1270        // memory will be freed in a big chunk by the PoolAllocator.
   1271        return true;
   1272    }
   1273    return false;
   1274 }
   1275 
   1276 bool TCompiler::initBuiltInSymbolTable(const ShBuiltInResources &resources)
   1277 {
   1278    if (resources.MaxDrawBuffers < 1)
   1279    {
   1280        return false;
   1281    }
   1282    if (resources.EXT_blend_func_extended && resources.MaxDualSourceDrawBuffers < 1)
   1283    {
   1284        return false;
   1285    }
   1286 
   1287    mSymbolTable.initializeBuiltIns(mShaderType, mShaderSpec, resources);
   1288 
   1289    return true;
   1290 }
   1291 
   1292 void TCompiler::setResourceString()
   1293 {
   1294    std::ostringstream strstream = sh::InitializeStream<std::ostringstream>();
   1295 
   1296    // clang-format off
   1297    strstream << ":MaxVertexAttribs:" << mResources.MaxVertexAttribs
   1298        << ":MaxVertexUniformVectors:" << mResources.MaxVertexUniformVectors
   1299        << ":MaxVaryingVectors:" << mResources.MaxVaryingVectors
   1300        << ":MaxVertexTextureImageUnits:" << mResources.MaxVertexTextureImageUnits
   1301        << ":MaxCombinedTextureImageUnits:" << mResources.MaxCombinedTextureImageUnits
   1302        << ":MaxTextureImageUnits:" << mResources.MaxTextureImageUnits
   1303        << ":MaxFragmentUniformVectors:" << mResources.MaxFragmentUniformVectors
   1304        << ":MaxDrawBuffers:" << mResources.MaxDrawBuffers
   1305        << ":OES_standard_derivatives:" << mResources.OES_standard_derivatives
   1306        << ":OES_EGL_image_external:" << mResources.OES_EGL_image_external
   1307        << ":OES_EGL_image_external_essl3:" << mResources.OES_EGL_image_external_essl3
   1308        << ":NV_EGL_stream_consumer_external:" << mResources.NV_EGL_stream_consumer_external
   1309        << ":ARB_texture_rectangle:" << mResources.ARB_texture_rectangle
   1310        << ":EXT_draw_buffers:" << mResources.EXT_draw_buffers
   1311        << ":FragmentPrecisionHigh:" << mResources.FragmentPrecisionHigh
   1312        << ":MaxExpressionComplexity:" << mResources.MaxExpressionComplexity
   1313        << ":MaxCallStackDepth:" << mResources.MaxCallStackDepth
   1314        << ":MaxFunctionParameters:" << mResources.MaxFunctionParameters
   1315        << ":EXT_blend_func_extended:" << mResources.EXT_blend_func_extended
   1316        << ":EXT_frag_depth:" << mResources.EXT_frag_depth
   1317        << ":EXT_primitive_bounding_box:" << mResources.EXT_primitive_bounding_box
   1318        << ":OES_primitive_bounding_box:" << mResources.OES_primitive_bounding_box
   1319        << ":EXT_shader_texture_lod:" << mResources.EXT_shader_texture_lod
   1320        << ":EXT_shader_framebuffer_fetch:" << mResources.EXT_shader_framebuffer_fetch
   1321        << ":EXT_shader_framebuffer_fetch_non_coherent:" << mResources.EXT_shader_framebuffer_fetch_non_coherent
   1322        << ":NV_shader_framebuffer_fetch:" << mResources.NV_shader_framebuffer_fetch
   1323        << ":ARM_shader_framebuffer_fetch:" << mResources.ARM_shader_framebuffer_fetch
   1324        << ":OVR_multiview2:" << mResources.OVR_multiview2
   1325        << ":OVR_multiview:" << mResources.OVR_multiview
   1326        << ":EXT_YUV_target:" << mResources.EXT_YUV_target
   1327        << ":EXT_geometry_shader:" << mResources.EXT_geometry_shader
   1328        << ":OES_geometry_shader:" << mResources.OES_geometry_shader
   1329        << ":OES_shader_io_blocks:" << mResources.OES_shader_io_blocks
   1330        << ":EXT_shader_io_blocks:" << mResources.EXT_shader_io_blocks
   1331        << ":EXT_gpu_shader5:" << mResources.EXT_gpu_shader5
   1332        << ":OES_texture_3D:" << mResources.OES_texture_3D
   1333        << ":MaxVertexOutputVectors:" << mResources.MaxVertexOutputVectors
   1334        << ":MaxFragmentInputVectors:" << mResources.MaxFragmentInputVectors
   1335        << ":MinProgramTexelOffset:" << mResources.MinProgramTexelOffset
   1336        << ":MaxProgramTexelOffset:" << mResources.MaxProgramTexelOffset
   1337        << ":MaxDualSourceDrawBuffers:" << mResources.MaxDualSourceDrawBuffers
   1338        << ":MaxViewsOVR:" << mResources.MaxViewsOVR
   1339        << ":NV_draw_buffers:" << mResources.NV_draw_buffers
   1340        << ":ANGLE_multi_draw:" << mResources.ANGLE_multi_draw
   1341        << ":ANGLE_base_vertex_base_instance_shader_builtin:" << mResources.ANGLE_base_vertex_base_instance_shader_builtin
   1342        << ":APPLE_clip_distance:" << mResources.APPLE_clip_distance
   1343        << ":OES_texture_cube_map_array:" << mResources.OES_texture_cube_map_array
   1344        << ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array
   1345        << ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers
   1346        << ":OES_shader_multisample_interpolation:" << mResources.OES_shader_multisample_interpolation
   1347        << ":OES_shader_image_atomic:" << mResources.OES_shader_image_atomic
   1348        << ":EXT_tessellation_shader:" << mResources.EXT_tessellation_shader
   1349        << ":OES_texture_buffer:" << mResources.OES_texture_buffer
   1350        << ":EXT_texture_buffer:" << mResources.EXT_texture_buffer
   1351        << ":OES_sample_variables:" << mResources.OES_sample_variables
   1352        << ":EXT_clip_cull_distance:" << mResources.EXT_clip_cull_distance
   1353        << ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset
   1354        << ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset
   1355        << ":MaxImageUnits:" << mResources.MaxImageUnits
   1356        << ":MaxSamples:" << mResources.MaxSamples
   1357        << ":MaxVertexImageUniforms:" << mResources.MaxVertexImageUniforms
   1358        << ":MaxFragmentImageUniforms:" << mResources.MaxFragmentImageUniforms
   1359        << ":MaxComputeImageUniforms:" << mResources.MaxComputeImageUniforms
   1360        << ":MaxCombinedImageUniforms:" << mResources.MaxCombinedImageUniforms
   1361        << ":MaxCombinedShaderOutputResources:" << mResources.MaxCombinedShaderOutputResources
   1362        << ":MaxComputeWorkGroupCountX:" << mResources.MaxComputeWorkGroupCount[0]
   1363        << ":MaxComputeWorkGroupCountY:" << mResources.MaxComputeWorkGroupCount[1]
   1364        << ":MaxComputeWorkGroupCountZ:" << mResources.MaxComputeWorkGroupCount[2]
   1365        << ":MaxComputeWorkGroupSizeX:" << mResources.MaxComputeWorkGroupSize[0]
   1366        << ":MaxComputeWorkGroupSizeY:" << mResources.MaxComputeWorkGroupSize[1]
   1367        << ":MaxComputeWorkGroupSizeZ:" << mResources.MaxComputeWorkGroupSize[2]
   1368        << ":MaxComputeUniformComponents:" << mResources.MaxComputeUniformComponents
   1369        << ":MaxComputeTextureImageUnits:" << mResources.MaxComputeTextureImageUnits
   1370        << ":MaxComputeAtomicCounters:" << mResources.MaxComputeAtomicCounters
   1371        << ":MaxComputeAtomicCounterBuffers:" << mResources.MaxComputeAtomicCounterBuffers
   1372        << ":MaxVertexAtomicCounters:" << mResources.MaxVertexAtomicCounters
   1373        << ":MaxFragmentAtomicCounters:" << mResources.MaxFragmentAtomicCounters
   1374        << ":MaxCombinedAtomicCounters:" << mResources.MaxCombinedAtomicCounters
   1375        << ":MaxAtomicCounterBindings:" << mResources.MaxAtomicCounterBindings
   1376        << ":MaxVertexAtomicCounterBuffers:" << mResources.MaxVertexAtomicCounterBuffers
   1377        << ":MaxFragmentAtomicCounterBuffers:" << mResources.MaxFragmentAtomicCounterBuffers
   1378        << ":MaxCombinedAtomicCounterBuffers:" << mResources.MaxCombinedAtomicCounterBuffers
   1379        << ":MaxAtomicCounterBufferSize:" << mResources.MaxAtomicCounterBufferSize
   1380        << ":MaxGeometryUniformComponents:" << mResources.MaxGeometryUniformComponents
   1381        << ":MaxGeometryUniformBlocks:" << mResources.MaxGeometryUniformBlocks
   1382        << ":MaxGeometryInputComponents:" << mResources.MaxGeometryInputComponents
   1383        << ":MaxGeometryOutputComponents:" << mResources.MaxGeometryOutputComponents
   1384        << ":MaxGeometryOutputVertices:" << mResources.MaxGeometryOutputVertices
   1385        << ":MaxGeometryTotalOutputComponents:" << mResources.MaxGeometryTotalOutputComponents
   1386        << ":MaxGeometryTextureImageUnits:" << mResources.MaxGeometryTextureImageUnits
   1387        << ":MaxGeometryAtomicCounterBuffers:" << mResources.MaxGeometryAtomicCounterBuffers
   1388        << ":MaxGeometryAtomicCounters:" << mResources.MaxGeometryAtomicCounters
   1389        << ":MaxGeometryShaderStorageBlocks:" << mResources.MaxGeometryShaderStorageBlocks
   1390        << ":MaxGeometryShaderInvocations:" << mResources.MaxGeometryShaderInvocations
   1391        << ":MaxGeometryImageUniforms:" << mResources.MaxGeometryImageUniforms
   1392        << ":MaxClipDistances" << mResources.MaxClipDistances
   1393        << ":MaxCullDistances" << mResources.MaxCullDistances
   1394        << ":MaxCombinedClipAndCullDistances" << mResources.MaxCombinedClipAndCullDistances
   1395        << ":MaxTessControlInputComponents:" << mResources.MaxTessControlInputComponents
   1396        << ":MaxTessControlOutputComponents:" << mResources.MaxTessControlOutputComponents
   1397        << ":MaxTessControlTextureImageUnits:" << mResources.MaxTessControlTextureImageUnits
   1398        << ":MaxTessControlUniformComponents:" << mResources.MaxTessControlUniformComponents
   1399        << ":MaxTessControlTotalOutputComponents:" << mResources.MaxTessControlTotalOutputComponents
   1400        << ":MaxTessControlImageUniforms:" << mResources.MaxTessControlImageUniforms
   1401        << ":MaxTessControlAtomicCounters:" << mResources.MaxTessControlAtomicCounters
   1402        << ":MaxTessControlAtomicCounterBuffers:" << mResources.MaxTessControlAtomicCounterBuffers
   1403        << ":MaxTessPatchComponents:" << mResources.MaxTessPatchComponents
   1404        << ":MaxPatchVertices:" << mResources.MaxPatchVertices
   1405        << ":MaxTessGenLevel:" << mResources.MaxTessGenLevel
   1406        << ":MaxTessEvaluationInputComponents:" << mResources.MaxTessEvaluationInputComponents
   1407        << ":MaxTessEvaluationOutputComponents:" << mResources.MaxTessEvaluationOutputComponents
   1408        << ":MaxTessEvaluationTextureImageUnits:" << mResources.MaxTessEvaluationTextureImageUnits
   1409        << ":MaxTessEvaluationUniformComponents:" << mResources.MaxTessEvaluationUniformComponents
   1410        << ":MaxTessEvaluationImageUniforms:" << mResources.MaxTessEvaluationImageUniforms
   1411        << ":MaxTessEvaluationAtomicCounters:" << mResources.MaxTessEvaluationAtomicCounters
   1412        << ":MaxTessEvaluationAtomicCounterBuffers:" << mResources.MaxTessEvaluationAtomicCounterBuffers;
   1413    // clang-format on
   1414 
   1415    mBuiltInResourcesString = strstream.str();
   1416 }
   1417 
   1418 void TCompiler::collectInterfaceBlocks()
   1419 {
   1420    ASSERT(mInterfaceBlocks.empty());
   1421    mInterfaceBlocks.reserve(mUniformBlocks.size() + mShaderStorageBlocks.size());
   1422    mInterfaceBlocks.insert(mInterfaceBlocks.end(), mUniformBlocks.begin(), mUniformBlocks.end());
   1423    mInterfaceBlocks.insert(mInterfaceBlocks.end(), mShaderStorageBlocks.begin(),
   1424                            mShaderStorageBlocks.end());
   1425 }
   1426 
   1427 void TCompiler::clearResults()
   1428 {
   1429    mInfoSink.info.erase();
   1430    mInfoSink.obj.erase();
   1431    mInfoSink.debug.erase();
   1432    mDiagnostics.resetErrorCount();
   1433 
   1434    mAttributes.clear();
   1435    mOutputVariables.clear();
   1436    mUniforms.clear();
   1437    mInputVaryings.clear();
   1438    mOutputVaryings.clear();
   1439    mSharedVariables.clear();
   1440    mInterfaceBlocks.clear();
   1441    mUniformBlocks.clear();
   1442    mShaderStorageBlocks.clear();
   1443    mVariablesCollected    = false;
   1444    mGLPositionInitialized = false;
   1445 
   1446    mNumViews = -1;
   1447 
   1448    mGeometryShaderInputPrimitiveType  = EptUndefined;
   1449    mGeometryShaderOutputPrimitiveType = EptUndefined;
   1450    mGeometryShaderInvocations         = 0;
   1451    mGeometryShaderMaxVertices         = -1;
   1452 
   1453    mTessControlShaderOutputVertices            = 0;
   1454    mTessEvaluationShaderInputPrimitiveType     = EtetUndefined;
   1455    mTessEvaluationShaderInputVertexSpacingType = EtetUndefined;
   1456    mTessEvaluationShaderInputOrderingType      = EtetUndefined;
   1457    mTessEvaluationShaderInputPointType         = EtetUndefined;
   1458 
   1459    mBuiltInFunctionEmulator.cleanup();
   1460 
   1461    mNameMap.clear();
   1462 
   1463    mSourcePath = nullptr;
   1464 
   1465    mSymbolTable.clearCompilationResults();
   1466 }
   1467 
   1468 bool TCompiler::initCallDag(TIntermNode *root)
   1469 {
   1470    mCallDag.clear();
   1471 
   1472    switch (mCallDag.init(root, &mDiagnostics))
   1473    {
   1474        case CallDAG::INITDAG_SUCCESS:
   1475            return true;
   1476        case CallDAG::INITDAG_RECURSION:
   1477        case CallDAG::INITDAG_UNDEFINED:
   1478            // Error message has already been written out.
   1479            ASSERT(mDiagnostics.numErrors() > 0);
   1480            return false;
   1481    }
   1482 
   1483    UNREACHABLE();
   1484    return true;
   1485 }
   1486 
   1487 bool TCompiler::checkCallDepth()
   1488 {
   1489    std::vector<int> depths(mCallDag.size());
   1490 
   1491    for (size_t i = 0; i < mCallDag.size(); i++)
   1492    {
   1493        int depth                     = 0;
   1494        const CallDAG::Record &record = mCallDag.getRecordFromIndex(i);
   1495 
   1496        for (int calleeIndex : record.callees)
   1497        {
   1498            depth = std::max(depth, depths[calleeIndex] + 1);
   1499        }
   1500 
   1501        depths[i] = depth;
   1502 
   1503        if (depth >= mResources.MaxCallStackDepth)
   1504        {
   1505            // Trace back the function chain to have a meaningful info log.
   1506            std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
   1507            errorStream << "Call stack too deep (larger than " << mResources.MaxCallStackDepth
   1508                        << ") with the following call chain: "
   1509                        << record.node->getFunction()->name();
   1510 
   1511            int currentFunction = static_cast<int>(i);
   1512            int currentDepth    = depth;
   1513 
   1514            while (currentFunction != -1)
   1515            {
   1516                errorStream
   1517                    << " -> "
   1518                    << mCallDag.getRecordFromIndex(currentFunction).node->getFunction()->name();
   1519 
   1520                int nextFunction = -1;
   1521                for (const int &calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees)
   1522                {
   1523                    if (depths[calleeIndex] == currentDepth - 1)
   1524                    {
   1525                        currentDepth--;
   1526                        nextFunction = calleeIndex;
   1527                    }
   1528                }
   1529 
   1530                currentFunction = nextFunction;
   1531            }
   1532 
   1533            std::string errorStr = errorStream.str();
   1534            mDiagnostics.globalError(errorStr.c_str());
   1535 
   1536            return false;
   1537        }
   1538    }
   1539 
   1540    return true;
   1541 }
   1542 
   1543 bool TCompiler::tagUsedFunctions()
   1544 {
   1545    // Search from main, starting from the end of the DAG as it usually is the root.
   1546    for (size_t i = mCallDag.size(); i-- > 0;)
   1547    {
   1548        if (mCallDag.getRecordFromIndex(i).node->getFunction()->isMain())
   1549        {
   1550            internalTagUsedFunction(i);
   1551            return true;
   1552        }
   1553    }
   1554 
   1555    mDiagnostics.globalError("Missing main()");
   1556    return false;
   1557 }
   1558 
   1559 void TCompiler::internalTagUsedFunction(size_t index)
   1560 {
   1561    if (mFunctionMetadata[index].used)
   1562    {
   1563        return;
   1564    }
   1565 
   1566    mFunctionMetadata[index].used = true;
   1567 
   1568    for (int calleeIndex : mCallDag.getRecordFromIndex(index).callees)
   1569    {
   1570        internalTagUsedFunction(calleeIndex);
   1571    }
   1572 }
   1573 
   1574 bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
   1575 {
   1576    TIntermSequence *sequence = root->getSequence();
   1577 
   1578    size_t writeIndex = 0;
   1579    for (size_t readIndex = 0; readIndex < sequence->size(); ++readIndex)
   1580    {
   1581        TIntermNode *node = sequence->at(readIndex);
   1582 
   1583        // Keep anything that's not unused.
   1584        const TFunction *function = nullptr;
   1585        const bool shouldPrune =
   1586            IsTopLevelNodeUnusedFunction(mCallDag, mFunctionMetadata, node, &function);
   1587        if (!shouldPrune)
   1588        {
   1589            (*sequence)[writeIndex++] = node;
   1590            continue;
   1591        }
   1592 
   1593        // If a function is unused, it may have a struct declaration in its return value which
   1594        // shouldn't be pruned.  In that case, replace the function definition with the struct
   1595        // definition.
   1596        ASSERT(function != nullptr);
   1597        const TType &returnType = function->getReturnType();
   1598        if (!returnType.isStructSpecifier())
   1599        {
   1600            continue;
   1601        }
   1602 
   1603        TVariable *structVariable =
   1604            new TVariable(&mSymbolTable, kEmptyImmutableString, &returnType, SymbolType::Empty);
   1605        TIntermSymbol *structSymbol           = new TIntermSymbol(structVariable);
   1606        TIntermDeclaration *structDeclaration = new TIntermDeclaration;
   1607        structDeclaration->appendDeclarator(structSymbol);
   1608 
   1609        structSymbol->setLine(node->getLine());
   1610        structDeclaration->setLine(node->getLine());
   1611 
   1612        (*sequence)[writeIndex++] = structDeclaration;
   1613    }
   1614 
   1615    sequence->resize(writeIndex);
   1616 
   1617    return validateAST(root);
   1618 }
   1619 
   1620 bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
   1621 {
   1622    if (!IsASTDepthBelowLimit(root, mResources.MaxExpressionComplexity))
   1623    {
   1624        mDiagnostics.globalError("Expression too complex.");
   1625        return false;
   1626    }
   1627 
   1628    if (!ValidateMaxParameters(root, mResources.MaxFunctionParameters))
   1629    {
   1630        mDiagnostics.globalError("Function has too many parameters.");
   1631        return false;
   1632    }
   1633 
   1634    return true;
   1635 }
   1636 
   1637 bool TCompiler::shouldCollectVariables(const ShCompileOptions &compileOptions)
   1638 {
   1639    return compileOptions.variables;
   1640 }
   1641 
   1642 bool TCompiler::wereVariablesCollected() const
   1643 {
   1644    return mVariablesCollected;
   1645 }
   1646 
   1647 bool TCompiler::initializeGLPosition(TIntermBlock *root)
   1648 {
   1649    sh::ShaderVariable var(GL_FLOAT_VEC4);
   1650    var.name = "gl_Position";
   1651    return InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion, mExtensionBehavior,
   1652                               false, false);
   1653 }
   1654 
   1655 bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
   1656 {
   1657    sh::InterfaceBlockList list;
   1658 
   1659    for (const sh::InterfaceBlock &block : mUniformBlocks)
   1660    {
   1661        if (!block.staticUse &&
   1662            (block.layout == sh::BLOCKLAYOUT_STD140 || block.layout == sh::BLOCKLAYOUT_SHARED))
   1663        {
   1664            list.push_back(block);
   1665        }
   1666    }
   1667 
   1668    return sh::UseInterfaceBlockFields(this, root, list, mSymbolTable);
   1669 }
   1670 
   1671 bool TCompiler::initializeOutputVariables(TIntermBlock *root)
   1672 {
   1673    InitVariableList list;
   1674    list.reserve(mOutputVaryings.size());
   1675    if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT)
   1676    {
   1677        for (const sh::ShaderVariable &var : mOutputVaryings)
   1678        {
   1679            list.push_back(var);
   1680            if (var.name == "gl_Position")
   1681            {
   1682                ASSERT(!mGLPositionInitialized);
   1683                mGLPositionInitialized = true;
   1684            }
   1685        }
   1686    }
   1687    else
   1688    {
   1689        ASSERT(mShaderType == GL_FRAGMENT_SHADER);
   1690        for (const sh::ShaderVariable &var : mOutputVariables)
   1691        {
   1692            // in-out variables represent the context of the framebuffer
   1693            // when the draw call starts, so they have to be considered
   1694            // as already initialized.
   1695            if (!var.isFragmentInOut)
   1696            {
   1697                list.push_back(var);
   1698            }
   1699        }
   1700    }
   1701    return InitializeVariables(this, root, list, &mSymbolTable, mShaderVersion, mExtensionBehavior,
   1702                               false, false);
   1703 }
   1704 
   1705 const TExtensionBehavior &TCompiler::getExtensionBehavior() const
   1706 {
   1707    return mExtensionBehavior;
   1708 }
   1709 
   1710 const char *TCompiler::getSourcePath() const
   1711 {
   1712    return mSourcePath;
   1713 }
   1714 
   1715 const ShBuiltInResources &TCompiler::getResources() const
   1716 {
   1717    return mResources;
   1718 }
   1719 
   1720 const BuiltInFunctionEmulator &TCompiler::getBuiltInFunctionEmulator() const
   1721 {
   1722    return mBuiltInFunctionEmulator;
   1723 }
   1724 
   1725 bool TCompiler::isVaryingDefined(const char *varyingName)
   1726 {
   1727    ASSERT(mVariablesCollected);
   1728    for (size_t ii = 0; ii < mInputVaryings.size(); ++ii)
   1729    {
   1730        if (mInputVaryings[ii].name == varyingName)
   1731        {
   1732            return true;
   1733        }
   1734    }
   1735    for (size_t ii = 0; ii < mOutputVaryings.size(); ++ii)
   1736    {
   1737        if (mOutputVaryings[ii].name == varyingName)
   1738        {
   1739            return true;
   1740        }
   1741    }
   1742 
   1743    return false;
   1744 }
   1745 
   1746 }  // namespace sh