107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org//
288f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org// Use of this source code is governed by a BSD-style license that can be
407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org// found in the LICENSE file.
507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org//
607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
717732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/BuiltInFunctionEmulator.h"
8d4a3a3171ce8b72123e4eaa85a3c5d2b3130878cJamie Madill#include "compiler/translator/Compiler.h"
917732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/DetectCallDepth.h"
1017732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ForLoopUnroll.h"
1117732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/Initialize.h"
1217732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/InitializeParseContext.h"
134a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo#include "compiler/translator/InitializeVariables.h"
146b9cb25980022d0c792d858bc6f6500c00a6c29dJamie Madill#include "compiler/translator/ParseContext.h"
15e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo#include "compiler/translator/RegenerateStructNames.h"
1617732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/RenameFunction.h"
17cd68fe7989afb5e5a9b1ae92ae1dae1478a9d1f6Zhenyao Mo#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
187cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo#include "compiler/translator/UnfoldShortCircuitAST.h"
1917732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ValidateLimitations.h"
2017732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ValidateOutputs.h"
2117732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/VariablePacker.h"
2217732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/depgraph/DependencyGraph.h"
2317732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/depgraph/DependencyGraphOutput.h"
2417732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
2517732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/timing/RestrictVertexShaderTiming.h"
26da1ed36a3ba807337ec1d5a2009238c00ce4caabshannon.woods@transgaming.com#include "third_party/compiler/ArrayBoundsClamper.h"
27183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill#include "angle_gl.h"
28aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill#include "common/utilities.h"
2907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
305508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madillbool IsWebGLBasedSpec(ShShaderSpec spec)
31430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com{
32430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com     return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
33430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com}
34430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com
357faf1a14deb3cdfc9f9137de95f9fc1552b603bdZhenyao Mosize_t GetGlobalMaxTokenSize(ShShaderSpec spec)
3688f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill{
3788f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    // WebGL defines a max token legnth of 256, while ES2 leaves max token
3888f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    // size undefined. ES3 defines a max size of 1024 characters.
397faf1a14deb3cdfc9f9137de95f9fc1552b603bdZhenyao Mo    if (IsWebGLBasedSpec(spec))
4088f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    {
4188f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill        return 256;
4288f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    }
4388f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    else
4488f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    {
4588f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill        return 1024;
4688f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    }
4788f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill}
4888f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill
49bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.orgnamespace {
504a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Moclass TScopedPoolAllocator
514a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
524a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  public:
534a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator)
544a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
55bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        mAllocator->push();
56bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org        SetGlobalPoolAllocator(mAllocator);
57bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    }
584a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    ~TScopedPoolAllocator()
594a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
60bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org        SetGlobalPoolAllocator(NULL);
61bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        mAllocator->pop();
62bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    }
63bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
644a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  private:
65bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    TPoolAllocator* mAllocator;
66bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi};
67bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi
684a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Moclass TScopedSymbolTableLevel
694a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
704a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  public:
714a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table)
724a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
73bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        ASSERT(mTable->atBuiltInLevel());
74bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        mTable->push();
75bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    }
764a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    ~TScopedSymbolTableLevel()
774a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
78bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        while (!mTable->atBuiltInLevel())
79bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi            mTable->pop();
80bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    }
81bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi
824a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  private:
83bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    TSymbolTable* mTable;
84bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org};
85bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org}  // namespace
86bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
874a667fe96e55df4713532e3830dd215ac7696f53Zhenyao MoTShHandleBase::TShHandleBase()
884a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
89bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    allocator.push();
90bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    SetGlobalPoolAllocator(&allocator);
91bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org}
92bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
934a667fe96e55df4713532e3830dd215ac7696f53Zhenyao MoTShHandleBase::~TShHandleBase()
944a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
95bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    SetGlobalPoolAllocator(NULL);
96bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    allocator.popAll();
97bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org}
98bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
99183bde5527317fa2208401e5e6b803ef51a0fdcbJamie MadillTCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
1004888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org    : shaderType(type),
101f420c42442136e63c8c475446e01da1f6bcf5d32zmo@google.com      shaderSpec(spec),
10268fe74aabbb4d8ae08aadcf22705f0d85a16e0b5Jamie Madill      outputType(output),
103eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill      maxUniformVectors(0),
104eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill      maxExpressionComplexity(0),
105eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill      maxCallStackDepth(0),
106cbb6b6a0416552b5e3fa8589194288532558ccb8shannon.woods%transgaming.com@gtempaccount.com      fragmentPrecisionHigh(false),
1071d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com      clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
1089996b8e6b16c43f8002eea64266b595f05a3a2d1zmo@google.com      builtInFunctionEmulator(type)
1094888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org{
1104888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org}
1114888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org
1124888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.orgTCompiler::~TCompiler()
1134888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org{
1144888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org}
1154888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org
1164888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.orgbool TCompiler::Init(const ShBuiltInResources& resources)
11707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
1180bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com    shaderVersion = 100;
119183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill    maxUniformVectors = (shaderType == GL_VERTEX_SHADER) ?
1208d8047995445882c73091578b889226323f38053gman@chromium.org        resources.MaxVertexUniformVectors :
1218d8047995445882c73091578b889226323f38053gman@chromium.org        resources.MaxFragmentUniformVectors;
122eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    maxExpressionComplexity = resources.MaxExpressionComplexity;
123eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    maxCallStackDepth = resources.MaxCallStackDepth;
124bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi
125bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    SetGlobalPoolAllocator(&allocator);
126bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
12707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Generate built-in symbol table.
12807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    if (!InitBuiltInSymbolTable(resources))
12907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org        return false;
13007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    InitExtensionBehavior(resources, extensionBehavior);
131cbb6b6a0416552b5e3fa8589194288532558ccb8shannon.woods%transgaming.com@gtempaccount.com    fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
132bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
1331d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
1341d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    clampingStrategy = resources.ArrayIndexClampingStrategy;
1351d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com
136c23f4611be61bccdbfe2a5c43f63c4d98537ef9fdaniel@transgaming.com    hashFunction = resources.HashFunction;
137c23f4611be61bccdbfe2a5c43f63c4d98537ef9fdaniel@transgaming.com
13807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    return true;
13907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
14007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
14107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.orgbool TCompiler::compile(const char* const shaderStrings[],
142d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com                        size_t numStrings,
14307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org                        int compileOptions)
14407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
145bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    TScopedPoolAllocator scopedAlloc(&allocator);
14607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    clearResults();
14707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
14807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    if (numStrings == 0)
14907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org        return true;
15007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
151b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    // If compiling for WebGL, validate loop and indexing as well.
1525508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madill    if (IsWebGLBasedSpec(shaderSpec))
153b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
1541f29954dc7d433d6a69c4ec7bd07b7153f8d4b99alokp@chromium.org
1550f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    // First string is path of source file if flag is set. The actual source follows.
1560f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    const char* sourcePath = NULL;
157d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com    size_t firstSource = 0;
1580f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    if (compileOptions & SH_SOURCE_PATH)
1590f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    {
1600f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org        sourcePath = shaderStrings[0];
1610f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org        ++firstSource;
1620f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    }
1630f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org
16407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    TIntermediate intermediate(infoSink);
16507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
166dc4b4f85516fec32b746d1841c1df00865d96214zmo@google.com                               shaderType, shaderSpec, compileOptions, true,
1670f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org                               sourcePath, infoSink);
168cbb6b6a0416552b5e3fa8589194288532558ccb8shannon.woods%transgaming.com@gtempaccount.com    parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
1698156b6be065905c22db8f5dc3ab0fb715b0e1b52Alok Priyadarshi    SetGlobalParseContext(&parseContext);
17007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
17107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // We preserve symbols at the built-in level from compile-to-compile.
17207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Start pushing the user-defined symbols at global level.
173bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
17407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
17507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Parse shader.
17607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    bool success =
1770f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org        (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
17807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org        (parseContext.treeRoot != NULL);
1790bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com
1805524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com    shaderVersion = parseContext.getShaderVersion();
1810bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com
1824a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    if (success)
1834a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
184b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        TIntermNode* root = parseContext.treeRoot;
185b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        success = intermediate.postProcess(root);
186b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org
1876654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        // Disallow expressions deemed too complex.
1886654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
1896654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill            success = limitExpressionComplexity(root);
1906654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill
191b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com        if (success)
192eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill            success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
193b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com
194183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill        if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER)
19505a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill            success = validateOutputs(root);
19605a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill
197b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
198b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org            success = validateLimitations(root);
19907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
20066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
20177222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com            success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
20266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
203430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com        if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
204430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com            rewriteCSSShader(root);
205430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com
2060c6bb7a653f52baa3dab4492a3599ddcacf076edzmo@google.com        // Unroll for-loop markup needs to happen after validateLimitations pass.
2070c6bb7a653f52baa3dab4492a3599ddcacf076edzmo@google.com        if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
2083cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo        {
2093cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo            ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex);
210550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            root->traverse(&marker);
211550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo        }
212550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo        if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX))
2133cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo        {
2143cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo            ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex);
215550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            root->traverse(&marker);
216550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            if (marker.samplerArrayIndexIsFloatLoopIndex())
217550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            {
218550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo                infoSink.info.prefix(EPrefixError);
219550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo                infoSink.info << "sampler array index is float loop index";
220550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo                success = false;
221550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            }
222550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo        }
2230c6bb7a653f52baa3dab4492a3599ddcacf076edzmo@google.com
22432e97315e2a55557ad7c372239e0823a81243221zmo@google.com        // Built-in function emulation needs to happen after validateLimitations pass.
22532e97315e2a55557ad7c372239e0823a81243221zmo@google.com        if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
22632e97315e2a55557ad7c372239e0823a81243221zmo@google.com            builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
22732e97315e2a55557ad7c372239e0823a81243221zmo@google.com
2284167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com        // Clamping uniform array bounds needs to happen after validateLimitations pass.
2294167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com        if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
2304167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com            arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
2314167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com
232183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill        if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION))
2334a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            initializeGLPosition(root);
234ac44cd2b072916b83f079bbfda66636491279d2eZhenyao Mo
2354a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
2364a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
2377cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo            UnfoldShortCircuitAST unfoldShortCircuit;
2387cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo            root->traverse(&unfoldShortCircuit);
2397cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo            unfoldShortCircuit.updateTree();
2407cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo        }
2417cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo
2424a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (success && (compileOptions & SH_VARIABLES))
2434a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
24474da9f2f24093e828b30071cebc09f99088fc13cZhenyao Mo            collectVariables(root);
2454a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
2464a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            {
2478d8047995445882c73091578b889226323f38053gman@chromium.org                success = enforcePackingRestrictions();
2484a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                if (!success)
2494a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                {
250075edd84dd682b91279132317d34b09e8028ae6fJamie Madill                    infoSink.info.prefix(EPrefixError);
251075edd84dd682b91279132317d34b09e8028ae6fJamie Madill                    infoSink.info << "too many uniforms";
2528d8047995445882c73091578b889226323f38053gman@chromium.org                }
2538d8047995445882c73091578b889226323f38053gman@chromium.org            }
254183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill            if (success && shaderType == GL_VERTEX_SHADER &&
2554a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE))
2564a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                initializeVaryingsWithoutStaticUse(root);
2578d8047995445882c73091578b889226323f38053gman@chromium.org        }
258fd747b861195a03df634a722a9cf3505dcd41253zmo@google.com
259cd68fe7989afb5e5a9b1ae92ae1dae1478a9d1f6Zhenyao Mo        if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
260cd68fe7989afb5e5a9b1ae92ae1dae1478a9d1f6Zhenyao Mo        {
261daf565720b9e26a004e8716a3f52d4a63b988217Zhenyao Mo            ScalarizeVecAndMatConstructorArgs scalarizer(
262daf565720b9e26a004e8716a3f52d4a63b988217Zhenyao Mo                shaderType, fragmentPrecisionHigh);
263cd68fe7989afb5e5a9b1ae92ae1dae1478a9d1f6Zhenyao Mo            root->traverse(&scalarizer);
264cd68fe7989afb5e5a9b1ae92ae1dae1478a9d1f6Zhenyao Mo        }
265cd68fe7989afb5e5a9b1ae92ae1dae1478a9d1f6Zhenyao Mo
266e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
267e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        {
268e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo            RegenerateStructNames gen(symbolTable, shaderVersion);
269e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo            root->traverse(&gen);
270e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        }
271e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
2724888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org        if (success && (compileOptions & SH_INTERMEDIATE_TREE))
273b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org            intermediate.outputTree(root);
27407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
2754888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org        if (success && (compileOptions & SH_OBJECT_CODE))
276b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org            translate(root);
27707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    }
27807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
27907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Cleanup memory.
28007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    intermediate.remove(parseContext.treeRoot);
2817faf1a14deb3cdfc9f9137de95f9fc1552b603bdZhenyao Mo    SetGlobalParseContext(NULL);
28207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    return success;
28307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
28407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
28549a8887b73345356e147702be9eeb5b40236953cNicolas Capensbool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
28607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
28718b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com    compileResources = resources;
2882d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    setResourceString();
2892ac0be9df9be957eb8fe504a88fa2e10c8ae9dc9shannonwoods@chromium.org
29049a8887b73345356e147702be9eeb5b40236953cNicolas Capens    assert(symbolTable.isEmpty());
29149a8887b73345356e147702be9eeb5b40236953cNicolas Capens    symbolTable.push();   // COMMON_BUILTINS
29249a8887b73345356e147702be9eeb5b40236953cNicolas Capens    symbolTable.push();   // ESSL1_BUILTINS
29349a8887b73345356e147702be9eeb5b40236953cNicolas Capens    symbolTable.push();   // ESSL3_BUILTINS
29449a8887b73345356e147702be9eeb5b40236953cNicolas Capens
29549a8887b73345356e147702be9eeb5b40236953cNicolas Capens    TPublicType integer;
29649a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.type = EbtInt;
29749a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.primarySize = 1;
29849a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.secondarySize = 1;
29949a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.array = false;
30049a8887b73345356e147702be9eeb5b40236953cNicolas Capens
30149a8887b73345356e147702be9eeb5b40236953cNicolas Capens    TPublicType floatingPoint;
30249a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.type = EbtFloat;
30349a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.primarySize = 1;
30449a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.secondarySize = 1;
30549a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.array = false;
30649a8887b73345356e147702be9eeb5b40236953cNicolas Capens
307a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    TPublicType sampler;
308a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    sampler.primarySize = 1;
309a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    sampler.secondarySize = 1;
310a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    sampler.array = false;
311a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo
31249a8887b73345356e147702be9eeb5b40236953cNicolas Capens    switch(shaderType)
31349a8887b73345356e147702be9eeb5b40236953cNicolas Capens    {
314183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill      case GL_FRAGMENT_SHADER:
31549a8887b73345356e147702be9eeb5b40236953cNicolas Capens        symbolTable.setDefaultPrecision(integer, EbpMedium);
31649a8887b73345356e147702be9eeb5b40236953cNicolas Capens        break;
317183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill      case GL_VERTEX_SHADER:
31849a8887b73345356e147702be9eeb5b40236953cNicolas Capens        symbolTable.setDefaultPrecision(integer, EbpHigh);
31949a8887b73345356e147702be9eeb5b40236953cNicolas Capens        symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
32049a8887b73345356e147702be9eeb5b40236953cNicolas Capens        break;
3214a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      default:
3224a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        assert(false && "Language not supported");
32349a8887b73345356e147702be9eeb5b40236953cNicolas Capens    }
324a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    // We set defaults for all the sampler types, even those that are
325a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    // only available if an extension exists.
326a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    for (int samplerType = EbtGuardSamplerBegin + 1;
3274a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo         samplerType < EbtGuardSamplerEnd; ++samplerType)
3284a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
329a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo        sampler.type = static_cast<TBasicType>(samplerType);
330a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo        symbolTable.setDefaultPrecision(sampler, EbpLow);
331a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    }
33249a8887b73345356e147702be9eeb5b40236953cNicolas Capens
3331b45214aef6439fdeb6291e9d9fd1da61dec618cJamie Madill    InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
3342ac0be9df9be957eb8fe504a88fa2e10c8ae9dc9shannonwoods@chromium.org
33549a8887b73345356e147702be9eeb5b40236953cNicolas Capens    IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
33649a8887b73345356e147702be9eeb5b40236953cNicolas Capens
33749a8887b73345356e147702be9eeb5b40236953cNicolas Capens    return true;
33807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
33907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
3402d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woodsvoid TCompiler::setResourceString()
3412d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods{
3422d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    std::ostringstream strstream;
3432d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
3442d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
3452d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
3462d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
3472d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
3482d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
3492d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
3502d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
3512d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
3522d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
3532d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
3542d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
3552d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
3562d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
3572d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
3582d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
3592d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
3602d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
3612d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
3622d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
3632d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
3642d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods
3652d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    builtInResourcesString = strstream.str();
3662d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods}
3672d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods
36807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.orgvoid TCompiler::clearResults()
36907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
3704167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com    arrayBoundsClamper.Cleanup();
37107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    infoSink.info.erase();
37207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    infoSink.obj.erase();
37307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    infoSink.debug.erase();
37407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
375ed27c7296c9bc4e9d9901943a8a0147513d11fc6Jamie Madill    attributes.clear();
376ed27c7296c9bc4e9d9901943a8a0147513d11fc6Jamie Madill    outputVariables.clear();
37707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    uniforms.clear();
37823a8a433529d9db23882c702a29d5e594841563dJamie Madill    expandedUniforms.clear();
379d2d340b0da87296b1ec04799ef4c811966bfb7aeZhenyao Mo    varyings.clear();
38023a8a433529d9db23882c702a29d5e594841563dJamie Madill    expandedVaryings.clear();
381ed27c7296c9bc4e9d9901943a8a0147513d11fc6Jamie Madill    interfaceBlocks.clear();
382a3b4ab4c2beb1c020e474007ded4bed4a2383601zmo@google.com
383a3b4ab4c2beb1c020e474007ded4bed4a2383601zmo@google.com    builtInFunctionEmulator.Cleanup();
3840aa3b5a2b216c9033e7bb59f6dde3acf46cf2260daniel@transgaming.com
3850aa3b5a2b216c9033e7bb59f6dde3acf46cf2260daniel@transgaming.com    nameMap.clear();
38607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
38707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
388eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madillbool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
389b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com{
390eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
391b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com    root->traverse(&detect);
3924a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    switch (detect.detectCallDepth())
3934a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
3944a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorNone:
3954a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return true;
3964a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorMissingMain:
3974a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info.prefix(EPrefixError);
3984a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info << "Missing main()";
3994a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
4004a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorRecursion:
4014a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info.prefix(EPrefixError);
4024a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info << "Function recursion detected";
4034a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
4044a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorMaxDepthExceeded:
4054a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info.prefix(EPrefixError);
4064a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info << "Function call stack too deep";
4074a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
4084a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      default:
4094a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        UNREACHABLE();
4104a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
411b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com    }
412b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com}
413b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com
41405a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madillbool TCompiler::validateOutputs(TIntermNode* root)
41505a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill{
41605a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill    ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers);
41705a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill    root->traverse(&validateOutputs);
41805a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill    return (validateOutputs.numErrors() == 0);
41905a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill}
42005a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill
421430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.comvoid TCompiler::rewriteCSSShader(TIntermNode* root)
422430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com{
423430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com    RenameFunction renamer("main(", "css_main(");
424430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com    root->traverse(&renamer);
425430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com}
426430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com
4274a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mobool TCompiler::validateLimitations(TIntermNode* root)
4284a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
429b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    ValidateLimitations validate(shaderType, infoSink.info);
430b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    root->traverse(&validate);
431b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    return validate.numErrors() == 0;
432b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org}
433b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org
43477222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.combool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
43566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
4364a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    if (shaderSpec != SH_WEBGL_SPEC)
4374a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
43866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
43966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return false;
44066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
44166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
442183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill    if (shaderType == GL_FRAGMENT_SHADER)
4434a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
44466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TDependencyGraph graph(root);
44566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
44666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        // Output any errors first.
44777222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com        bool success = enforceFragmentShaderTimingRestrictions(graph);
4485508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madill
44966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        // Then, output the dependency graph.
4504a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (outputGraph)
4514a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
45266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            TDependencyGraphOutput output(infoSink.info);
45366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            output.outputAllSpanningTrees(graph);
45466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
4555508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madill
45666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return success;
45766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
4584a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    else
4594a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
46077222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com        return enforceVertexShaderTimingRestrictions(root);
46166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
46266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
46366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
464eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madillbool TCompiler::limitExpressionComplexity(TIntermNode* root)
465eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill{
4666654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    TMaxDepthTraverser traverser(maxExpressionComplexity+1);
467eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    root->traverse(&traverser);
4686654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill
4696654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    if (traverser.getMaxDepth() > maxExpressionComplexity)
4706654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    {
4716654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        infoSink.info << "Expression too complex.";
4726654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        return false;
4736654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    }
4746654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill
475eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    TDependencyGraph graph(root);
476eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill
477eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
478eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill         iter != graph.endUserDefinedFunctionCalls();
479eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill         ++iter)
480eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    {
481eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill        TGraphFunctionCall* samplerSymbol = *iter;
482eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill        TDependencyGraphTraverser graphTraverser;
483eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill        samplerSymbol->traverse(&graphTraverser);
484eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    }
485eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill
486eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    return true;
487eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill}
488eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill
48977222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.combool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
49066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
49177222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com    RestrictFragmentShaderTiming restrictor(infoSink.info);
49266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    restrictor.enforceRestrictions(graph);
49366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return restrictor.numErrors() == 0;
49466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
49566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
49677222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.combool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
49766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
49877222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com    RestrictVertexShaderTiming restrictor(infoSink.info);
49966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    restrictor.enforceRestrictions(root);
50066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return restrictor.numErrors() == 0;
50166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
50266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
50374da9f2f24093e828b30071cebc09f99088fc13cZhenyao Movoid TCompiler::collectVariables(TIntermNode* root)
50407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
505a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill    sh::CollectVariables collect(&attributes,
506a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill                                 &outputVariables,
507a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill                                 &uniforms,
508a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill                                 &varyings,
509a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill                                 &interfaceBlocks,
510a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill                                 hashFunction);
51107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    root->traverse(&collect);
51223a8a433529d9db23882c702a29d5e594841563dJamie Madill
51323a8a433529d9db23882c702a29d5e594841563dJamie Madill    // For backwards compatiblity with ShGetVariableInfo, expand struct
51423a8a433529d9db23882c702a29d5e594841563dJamie Madill    // uniforms and varyings into separate variables for each field.
515a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill    sh::ExpandVariables(uniforms, &expandedUniforms);
516a2fbb84095e91eec3957d0a1707dc740f0e62c50Jamie Madill    sh::ExpandVariables(varyings, &expandedVaryings);
51707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
518fd747b861195a03df634a722a9cf3505dcd41253zmo@google.com
5198d8047995445882c73091578b889226323f38053gman@chromium.orgbool TCompiler::enforcePackingRestrictions()
5208d8047995445882c73091578b889226323f38053gman@chromium.org{
5218d8047995445882c73091578b889226323f38053gman@chromium.org    VariablePacker packer;
52223a8a433529d9db23882c702a29d5e594841563dJamie Madill    return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
5238d8047995445882c73091578b889226323f38053gman@chromium.org}
5248d8047995445882c73091578b889226323f38053gman@chromium.org
5254a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Movoid TCompiler::initializeGLPosition(TIntermNode* root)
5264a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
5274a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables::InitVariableInfoList variables;
5284a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables::InitVariableInfo var(
5294a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4));
5304a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    variables.push_back(var);
5314a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables initializer(variables);
5324a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    root->traverse(&initializer);
5334a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo}
5344a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo
5354a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Movoid TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root)
5364a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
5374a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables::InitVariableInfoList variables;
5384a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    for (size_t ii = 0; ii < varyings.size(); ++ii)
5394a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
540a718c1e00264edf434aeddf7beb14f4fae0f07a0Jamie Madill        const sh::Varying& varying = varyings[ii];
5414a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (varying.staticUse)
5424a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            continue;
543aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill        unsigned char primarySize = static_cast<unsigned char>(gl::VariableColumnCount(varying.type));
544aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill        unsigned char secondarySize = static_cast<unsigned char>(gl::VariableRowCount(varying.type));
545a718c1e00264edf434aeddf7beb14f4fae0f07a0Jamie Madill        TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray());
5464a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        TString name = varying.name.c_str();
547a718c1e00264edf434aeddf7beb14f4fae0f07a0Jamie Madill        if (varying.isArray())
5484a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
549a718c1e00264edf434aeddf7beb14f4fae0f07a0Jamie Madill            type.setArraySize(varying.arraySize);
5504a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            name = name.substr(0, name.find_first_of('['));
5514a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        }
5524a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo
5534a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        InitializeVariables::InitVariableInfo var(name, type);
5544a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        variables.push_back(var);
5554a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    }
5564a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables initializer(variables);
5574a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    root->traverse(&initializer);
5584a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo}
5594a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo
5605601ea0d66442518d4745bb02b7619485b9d305bzmo@google.comconst TExtensionBehavior& TCompiler::getExtensionBehavior() const
5615601ea0d66442518d4745bb02b7619485b9d305bzmo@google.com{
5625601ea0d66442518d4745bb02b7619485b9d305bzmo@google.com    return extensionBehavior;
5635601ea0d66442518d4745bb02b7619485b9d305bzmo@google.com}
56432e97315e2a55557ad7c372239e0823a81243221zmo@google.com
56518b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.comconst ShBuiltInResources& TCompiler::getResources() const
56618b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com{
56718b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com    return compileResources;
56818b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com}
56918b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com
5701d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.comconst ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
57132e97315e2a55557ad7c372239e0823a81243221zmo@google.com{
5721d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    return arrayBoundsClamper;
57332e97315e2a55557ad7c372239e0823a81243221zmo@google.com}
5744167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com
5751d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.comShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
5764167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com{
5771d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    return clampingStrategy;
5784167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com}
5794167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com
5801d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.comconst BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
5811d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com{
5821d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    return builtInFunctionEmulator;
5831d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com}
584