diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/angle/src/compiler | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/angle/src/compiler')
168 files changed, 16342 insertions, 11422 deletions
diff --git a/chromium/third_party/angle/src/compiler/BaseTypes.h b/chromium/third_party/angle/src/compiler/BaseTypes.h deleted file mode 100644 index 1631f4f779f..00000000000 --- a/chromium/third_party/angle/src/compiler/BaseTypes.h +++ /dev/null @@ -1,148 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef _BASICTYPES_INCLUDED_ -#define _BASICTYPES_INCLUDED_ - -// -// Precision qualifiers -// -enum TPrecision -{ - // These need to be kept sorted - EbpUndefined, - EbpLow, - EbpMedium, - EbpHigh -}; - -inline const char* getPrecisionString(TPrecision p) -{ - switch(p) - { - case EbpHigh: return "highp"; break; - case EbpMedium: return "mediump"; break; - case EbpLow: return "lowp"; break; - default: return "mediump"; break; // Safest fallback - } -} - -// -// Basic type. Arrays, vectors, etc., are orthogonal to this. -// -enum TBasicType -{ - EbtVoid, - EbtFloat, - EbtInt, - EbtBool, - EbtGuardSamplerBegin, // non type: see implementation of IsSampler() - EbtSampler2D, - EbtSamplerCube, - EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists. - EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists. - EbtGuardSamplerEnd, // non type: see implementation of IsSampler() - EbtStruct, - EbtAddress, // should be deprecated?? - EbtInvariant // used as a type when qualifying a previously declared variable as being invariant -}; - -inline const char* getBasicString(TBasicType t) -{ - switch (t) - { - case EbtVoid: return "void"; break; - case EbtFloat: return "float"; break; - case EbtInt: return "int"; break; - case EbtBool: return "bool"; break; - case EbtSampler2D: return "sampler2D"; break; - case EbtSamplerCube: return "samplerCube"; break; - case EbtSamplerExternalOES: return "samplerExternalOES"; break; - case EbtSampler2DRect: return "sampler2DRect"; break; - case EbtStruct: return "structure"; break; - default: return "unknown type"; - } -} - -inline bool IsSampler(TBasicType type) -{ - return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd; -} - -// -// Qualifiers and built-ins. These are mainly used to see what can be read -// or written, and by the machine dependent translator to know which registers -// to allocate variables in. Since built-ins tend to go to different registers -// than varying or uniform, it makes sense they are peers, not sub-classes. -// -enum TQualifier -{ - EvqTemporary, // For temporaries (within a function), read/write - EvqGlobal, // For globals read/write - EvqConst, // User defined constants and non-output parameters in functions - EvqAttribute, // Readonly - EvqVaryingIn, // readonly, fragment shaders only - EvqVaryingOut, // vertex shaders only read/write - EvqInvariantVaryingIn, // readonly, fragment shaders only - EvqInvariantVaryingOut, // vertex shaders only read/write - EvqUniform, // Readonly, vertex and fragment - - // parameters - EvqIn, - EvqOut, - EvqInOut, - EvqConstReadOnly, - - // built-ins written by vertex shader - EvqPosition, - EvqPointSize, - - // built-ins read by fragment shader - EvqFragCoord, - EvqFrontFacing, - EvqPointCoord, - - // built-ins written by fragment shader - EvqFragColor, - EvqFragData, - EvqFragDepth, - - // end of list - EvqLast -}; - -// -// This is just for debug print out, carried along with the definitions above. -// -inline const char* getQualifierString(TQualifier q) -{ - switch(q) - { - case EvqTemporary: return "Temporary"; break; - case EvqGlobal: return "Global"; break; - case EvqConst: return "const"; break; - case EvqConstReadOnly: return "const"; break; - case EvqAttribute: return "attribute"; break; - case EvqVaryingIn: return "varying"; break; - case EvqVaryingOut: return "varying"; break; - case EvqInvariantVaryingIn: return "invariant varying"; break; - case EvqInvariantVaryingOut:return "invariant varying"; break; - case EvqUniform: return "uniform"; break; - case EvqIn: return "in"; break; - case EvqOut: return "out"; break; - case EvqInOut: return "inout"; break; - case EvqPosition: return "Position"; break; - case EvqPointSize: return "PointSize"; break; - case EvqFragCoord: return "FragCoord"; break; - case EvqFrontFacing: return "FrontFacing"; break; - case EvqFragColor: return "FragColor"; break; - case EvqFragData: return "FragData"; break; - case EvqFragDepth: return "FragDepth"; break; - default: return "unknown qualifier"; - } -} - -#endif // _BASICTYPES_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/ForLoopUnroll.cpp b/chromium/third_party/angle/src/compiler/ForLoopUnroll.cpp deleted file mode 100644 index 27a13eababb..00000000000 --- a/chromium/third_party/angle/src/compiler/ForLoopUnroll.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/ForLoopUnroll.h" - -namespace { - -class IntegerForLoopUnrollMarker : public TIntermTraverser { -public: - - virtual bool visitLoop(Visit, TIntermLoop* node) - { - // This is called after ValidateLimitations pass, so all the ASSERT - // should never fail. - // See ValidateLimitations::validateForLoopInit(). - ASSERT(node); - ASSERT(node->getType() == ELoopFor); - ASSERT(node->getInit()); - TIntermAggregate* decl = node->getInit()->getAsAggregate(); - ASSERT(decl && decl->getOp() == EOpDeclaration); - TIntermSequence& declSeq = decl->getSequence(); - ASSERT(declSeq.size() == 1); - TIntermBinary* declInit = declSeq[0]->getAsBinaryNode(); - ASSERT(declInit && declInit->getOp() == EOpInitialize); - ASSERT(declInit->getLeft()); - TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode(); - ASSERT(symbol); - TBasicType type = symbol->getBasicType(); - ASSERT(type == EbtInt || type == EbtFloat); - if (type == EbtInt) - node->setUnrollFlag(true); - return true; - } - -}; - -} // anonymous namepsace - -void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info) -{ - ASSERT(node->getType() == ELoopFor); - ASSERT(node->getUnrollFlag()); - - TIntermNode* init = node->getInit(); - ASSERT(init != NULL); - TIntermAggregate* decl = init->getAsAggregate(); - ASSERT((decl != NULL) && (decl->getOp() == EOpDeclaration)); - TIntermSequence& declSeq = decl->getSequence(); - ASSERT(declSeq.size() == 1); - TIntermBinary* declInit = declSeq[0]->getAsBinaryNode(); - ASSERT((declInit != NULL) && (declInit->getOp() == EOpInitialize)); - TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode(); - ASSERT(symbol != NULL); - ASSERT(symbol->getBasicType() == EbtInt); - - info.id = symbol->getId(); - - ASSERT(declInit->getRight() != NULL); - TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion(); - ASSERT(initNode != NULL); - - info.initValue = evaluateIntConstant(initNode); - info.currentValue = info.initValue; - - TIntermNode* cond = node->getCondition(); - ASSERT(cond != NULL); - TIntermBinary* binOp = cond->getAsBinaryNode(); - ASSERT(binOp != NULL); - ASSERT(binOp->getRight() != NULL); - ASSERT(binOp->getRight()->getAsConstantUnion() != NULL); - - info.incrementValue = getLoopIncrement(node); - info.stopValue = evaluateIntConstant( - binOp->getRight()->getAsConstantUnion()); - info.op = binOp->getOp(); -} - -void ForLoopUnroll::Step() -{ - ASSERT(mLoopIndexStack.size() > 0); - TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1]; - info.currentValue += info.incrementValue; -} - -bool ForLoopUnroll::SatisfiesLoopCondition() -{ - ASSERT(mLoopIndexStack.size() > 0); - TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1]; - // Relational operator is one of: > >= < <= == or !=. - switch (info.op) { - case EOpEqual: - return (info.currentValue == info.stopValue); - case EOpNotEqual: - return (info.currentValue != info.stopValue); - case EOpLessThan: - return (info.currentValue < info.stopValue); - case EOpGreaterThan: - return (info.currentValue > info.stopValue); - case EOpLessThanEqual: - return (info.currentValue <= info.stopValue); - case EOpGreaterThanEqual: - return (info.currentValue >= info.stopValue); - default: - UNREACHABLE(); - } - return false; -} - -bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol) -{ - for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin(); - i != mLoopIndexStack.end(); - ++i) { - if (i->id == symbol->getId()) - return true; - } - return false; -} - -int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol) -{ - for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin(); - i != mLoopIndexStack.end(); - ++i) { - if (i->id == symbol->getId()) - return i->currentValue; - } - UNREACHABLE(); - return false; -} - -void ForLoopUnroll::Push(TLoopIndexInfo& info) -{ - mLoopIndexStack.push_back(info); -} - -void ForLoopUnroll::Pop() -{ - mLoopIndexStack.pop_back(); -} - -// static -void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling( - TIntermNode* root) -{ - ASSERT(root); - - IntegerForLoopUnrollMarker marker; - root->traverse(&marker); -} - -int ForLoopUnroll::getLoopIncrement(TIntermLoop* node) -{ - TIntermNode* expr = node->getExpression(); - ASSERT(expr != NULL); - // for expression has one of the following forms: - // loop_index++ - // loop_index-- - // loop_index += constant_expression - // loop_index -= constant_expression - // ++loop_index - // --loop_index - // The last two forms are not specified in the spec, but I am assuming - // its an oversight. - TIntermUnary* unOp = expr->getAsUnaryNode(); - TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode(); - - TOperator op = EOpNull; - TIntermConstantUnion* incrementNode = NULL; - if (unOp != NULL) { - op = unOp->getOp(); - } else if (binOp != NULL) { - op = binOp->getOp(); - ASSERT(binOp->getRight() != NULL); - incrementNode = binOp->getRight()->getAsConstantUnion(); - ASSERT(incrementNode != NULL); - } - - int increment = 0; - // The operator is one of: ++ -- += -=. - switch (op) { - case EOpPostIncrement: - case EOpPreIncrement: - ASSERT((unOp != NULL) && (binOp == NULL)); - increment = 1; - break; - case EOpPostDecrement: - case EOpPreDecrement: - ASSERT((unOp != NULL) && (binOp == NULL)); - increment = -1; - break; - case EOpAddAssign: - ASSERT((unOp == NULL) && (binOp != NULL)); - increment = evaluateIntConstant(incrementNode); - break; - case EOpSubAssign: - ASSERT((unOp == NULL) && (binOp != NULL)); - increment = - evaluateIntConstant(incrementNode); - break; - default: - ASSERT(false); - } - - return increment; -} - -int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node) -{ - ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL)); - return node->getIConst(0); -} - diff --git a/chromium/third_party/angle/src/compiler/ForLoopUnroll.h b/chromium/third_party/angle/src/compiler/ForLoopUnroll.h deleted file mode 100644 index 738b76925e4..00000000000 --- a/chromium/third_party/angle/src/compiler/ForLoopUnroll.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_FORLOOPUNROLL_H_ -#define COMPILER_FORLOOPUNROLL_H_ - -#include "compiler/intermediate.h" - -struct TLoopIndexInfo { - int id; - int initValue; - int stopValue; - int incrementValue; - TOperator op; - int currentValue; -}; - -class ForLoopUnroll { -public: - ForLoopUnroll() { } - - void FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info); - - // Update the info.currentValue for the next loop iteration. - void Step(); - - // Return false if loop condition is no longer satisfied. - bool SatisfiesLoopCondition(); - - // Check if the symbol is the index of a loop that's unrolled. - bool NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol); - - // Return the current value of a given loop index symbol. - int GetLoopIndexValue(TIntermSymbol* symbol); - - void Push(TLoopIndexInfo& info); - void Pop(); - - static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode* root); - -private: - int getLoopIncrement(TIntermLoop* node); - - int evaluateIntConstant(TIntermConstantUnion* node); - - TVector<TLoopIndexInfo> mLoopIndexStack; -}; - -#endif diff --git a/chromium/third_party/angle/src/compiler/Initialize.cpp b/chromium/third_party/angle/src/compiler/Initialize.cpp deleted file mode 100644 index 2cdbe17aa6d..00000000000 --- a/chromium/third_party/angle/src/compiler/Initialize.cpp +++ /dev/null @@ -1,564 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// -// Create strings that declare built-in definitions, add built-ins that -// cannot be expressed in the files, and establish mappings between -// built-in functions and operators. -// - -#include "compiler/Initialize.h" - -#include "compiler/intermediate.h" - -void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable) -{ - TType *float1 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 1); - TType *float2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2); - TType *float3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3); - TType *float4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4); - - TType *int2 = new TType(EbtInt, EbpUndefined, EvqGlobal, 2); - TType *int3 = new TType(EbtInt, EbpUndefined, EvqGlobal, 3); - TType *int4 = new TType(EbtInt, EbpUndefined, EvqGlobal, 4); - - // - // Angle and Trigonometric Functions. - // - symbolTable.insertBuiltIn(float1, "radians", float1); - symbolTable.insertBuiltIn(float2, "radians", float2); - symbolTable.insertBuiltIn(float3, "radians", float3); - symbolTable.insertBuiltIn(float4, "radians", float4); - - symbolTable.insertBuiltIn(float1, "degrees", float1); - symbolTable.insertBuiltIn(float2, "degrees", float2); - symbolTable.insertBuiltIn(float3, "degrees", float3); - symbolTable.insertBuiltIn(float4, "degrees", float4); - - symbolTable.insertBuiltIn(float1, "sin", float1); - symbolTable.insertBuiltIn(float2, "sin", float2); - symbolTable.insertBuiltIn(float3, "sin", float3); - symbolTable.insertBuiltIn(float4, "sin", float4); - - symbolTable.insertBuiltIn(float1, "cos", float1); - symbolTable.insertBuiltIn(float2, "cos", float2); - symbolTable.insertBuiltIn(float3, "cos", float3); - symbolTable.insertBuiltIn(float4, "cos", float4); - - symbolTable.insertBuiltIn(float1, "tan", float1); - symbolTable.insertBuiltIn(float2, "tan", float2); - symbolTable.insertBuiltIn(float3, "tan", float3); - symbolTable.insertBuiltIn(float4, "tan", float4); - - symbolTable.insertBuiltIn(float1, "asin", float1); - symbolTable.insertBuiltIn(float2, "asin", float2); - symbolTable.insertBuiltIn(float3, "asin", float3); - symbolTable.insertBuiltIn(float4, "asin", float4); - - symbolTable.insertBuiltIn(float1, "acos", float1); - symbolTable.insertBuiltIn(float2, "acos", float2); - symbolTable.insertBuiltIn(float3, "acos", float3); - symbolTable.insertBuiltIn(float4, "acos", float4); - - symbolTable.insertBuiltIn(float1, "atan", float1, float1); - symbolTable.insertBuiltIn(float2, "atan", float2, float2); - symbolTable.insertBuiltIn(float3, "atan", float3, float3); - symbolTable.insertBuiltIn(float4, "atan", float4, float4); - - symbolTable.insertBuiltIn(float1, "atan", float1); - symbolTable.insertBuiltIn(float2, "atan", float2); - symbolTable.insertBuiltIn(float3, "atan", float3); - symbolTable.insertBuiltIn(float4, "atan", float4); - - // - // Exponential Functions. - // - symbolTable.insertBuiltIn(float1, "pow", float1, float1); - symbolTable.insertBuiltIn(float2, "pow", float2, float2); - symbolTable.insertBuiltIn(float3, "pow", float3, float3); - symbolTable.insertBuiltIn(float4, "pow", float4, float4); - - symbolTable.insertBuiltIn(float1, "exp", float1); - symbolTable.insertBuiltIn(float2, "exp", float2); - symbolTable.insertBuiltIn(float3, "exp", float3); - symbolTable.insertBuiltIn(float4, "exp", float4); - - symbolTable.insertBuiltIn(float1, "log", float1); - symbolTable.insertBuiltIn(float2, "log", float2); - symbolTable.insertBuiltIn(float3, "log", float3); - symbolTable.insertBuiltIn(float4, "log", float4); - - symbolTable.insertBuiltIn(float1, "exp2", float1); - symbolTable.insertBuiltIn(float2, "exp2", float2); - symbolTable.insertBuiltIn(float3, "exp2", float3); - symbolTable.insertBuiltIn(float4, "exp2", float4); - - symbolTable.insertBuiltIn(float1, "log2", float1); - symbolTable.insertBuiltIn(float2, "log2", float2); - symbolTable.insertBuiltIn(float3, "log2", float3); - symbolTable.insertBuiltIn(float4, "log2", float4); - - symbolTable.insertBuiltIn(float1, "sqrt", float1); - symbolTable.insertBuiltIn(float2, "sqrt", float2); - symbolTable.insertBuiltIn(float3, "sqrt", float3); - symbolTable.insertBuiltIn(float4, "sqrt", float4); - - symbolTable.insertBuiltIn(float1, "inversesqrt", float1); - symbolTable.insertBuiltIn(float2, "inversesqrt", float2); - symbolTable.insertBuiltIn(float3, "inversesqrt", float3); - symbolTable.insertBuiltIn(float4, "inversesqrt", float4); - - // - // Common Functions. - // - symbolTable.insertBuiltIn(float1, "abs", float1); - symbolTable.insertBuiltIn(float2, "abs", float2); - symbolTable.insertBuiltIn(float3, "abs", float3); - symbolTable.insertBuiltIn(float4, "abs", float4); - - symbolTable.insertBuiltIn(float1, "sign", float1); - symbolTable.insertBuiltIn(float2, "sign", float2); - symbolTable.insertBuiltIn(float3, "sign", float3); - symbolTable.insertBuiltIn(float4, "sign", float4); - - symbolTable.insertBuiltIn(float1, "floor", float1); - symbolTable.insertBuiltIn(float2, "floor", float2); - symbolTable.insertBuiltIn(float3, "floor", float3); - symbolTable.insertBuiltIn(float4, "floor", float4); - - symbolTable.insertBuiltIn(float1, "ceil", float1); - symbolTable.insertBuiltIn(float2, "ceil", float2); - symbolTable.insertBuiltIn(float3, "ceil", float3); - symbolTable.insertBuiltIn(float4, "ceil", float4); - - symbolTable.insertBuiltIn(float1, "fract", float1); - symbolTable.insertBuiltIn(float2, "fract", float2); - symbolTable.insertBuiltIn(float3, "fract", float3); - symbolTable.insertBuiltIn(float4, "fract", float4); - - symbolTable.insertBuiltIn(float1, "mod", float1, float1); - symbolTable.insertBuiltIn(float2, "mod", float2, float1); - symbolTable.insertBuiltIn(float3, "mod", float3, float1); - symbolTable.insertBuiltIn(float4, "mod", float4, float1); - symbolTable.insertBuiltIn(float2, "mod", float2, float2); - symbolTable.insertBuiltIn(float3, "mod", float3, float3); - symbolTable.insertBuiltIn(float4, "mod", float4, float4); - - symbolTable.insertBuiltIn(float1, "min", float1, float1); - symbolTable.insertBuiltIn(float2, "min", float2, float1); - symbolTable.insertBuiltIn(float3, "min", float3, float1); - symbolTable.insertBuiltIn(float4, "min", float4, float1); - symbolTable.insertBuiltIn(float2, "min", float2, float2); - symbolTable.insertBuiltIn(float3, "min", float3, float3); - symbolTable.insertBuiltIn(float4, "min", float4, float4); - - symbolTable.insertBuiltIn(float1, "max", float1, float1); - symbolTable.insertBuiltIn(float2, "max", float2, float1); - symbolTable.insertBuiltIn(float3, "max", float3, float1); - symbolTable.insertBuiltIn(float4, "max", float4, float1); - symbolTable.insertBuiltIn(float2, "max", float2, float2); - symbolTable.insertBuiltIn(float3, "max", float3, float3); - symbolTable.insertBuiltIn(float4, "max", float4, float4); - - symbolTable.insertBuiltIn(float1, "clamp", float1, float1, float1); - symbolTable.insertBuiltIn(float2, "clamp", float2, float1, float1); - symbolTable.insertBuiltIn(float3, "clamp", float3, float1, float1); - symbolTable.insertBuiltIn(float4, "clamp", float4, float1, float1); - symbolTable.insertBuiltIn(float2, "clamp", float2, float2, float2); - symbolTable.insertBuiltIn(float3, "clamp", float3, float3, float3); - symbolTable.insertBuiltIn(float4, "clamp", float4, float4, float4); - - symbolTable.insertBuiltIn(float1, "mix", float1, float1, float1); - symbolTable.insertBuiltIn(float2, "mix", float2, float2, float1); - symbolTable.insertBuiltIn(float3, "mix", float3, float3, float1); - symbolTable.insertBuiltIn(float4, "mix", float4, float4, float1); - symbolTable.insertBuiltIn(float2, "mix", float2, float2, float2); - symbolTable.insertBuiltIn(float3, "mix", float3, float3, float3); - symbolTable.insertBuiltIn(float4, "mix", float4, float4, float4); - - symbolTable.insertBuiltIn(float1, "step", float1, float1); - symbolTable.insertBuiltIn(float2, "step", float2, float2); - symbolTable.insertBuiltIn(float3, "step", float3, float3); - symbolTable.insertBuiltIn(float4, "step", float4, float4); - symbolTable.insertBuiltIn(float2, "step", float1, float2); - symbolTable.insertBuiltIn(float3, "step", float1, float3); - symbolTable.insertBuiltIn(float4, "step", float1, float4); - - symbolTable.insertBuiltIn(float1, "smoothstep", float1, float1, float1); - symbolTable.insertBuiltIn(float2, "smoothstep", float2, float2, float2); - symbolTable.insertBuiltIn(float3, "smoothstep", float3, float3, float3); - symbolTable.insertBuiltIn(float4, "smoothstep", float4, float4, float4); - symbolTable.insertBuiltIn(float2, "smoothstep", float1, float1, float2); - symbolTable.insertBuiltIn(float3, "smoothstep", float1, float1, float3); - symbolTable.insertBuiltIn(float4, "smoothstep", float1, float1, float4); - - // - // Geometric Functions. - // - symbolTable.insertBuiltIn(float1, "length", float1); - symbolTable.insertBuiltIn(float1, "length", float2); - symbolTable.insertBuiltIn(float1, "length", float3); - symbolTable.insertBuiltIn(float1, "length", float4); - - symbolTable.insertBuiltIn(float1, "distance", float1, float1); - symbolTable.insertBuiltIn(float1, "distance", float2, float2); - symbolTable.insertBuiltIn(float1, "distance", float3, float3); - symbolTable.insertBuiltIn(float1, "distance", float4, float4); - - symbolTable.insertBuiltIn(float1, "dot", float1, float1); - symbolTable.insertBuiltIn(float1, "dot", float2, float2); - symbolTable.insertBuiltIn(float1, "dot", float3, float3); - symbolTable.insertBuiltIn(float1, "dot", float4, float4); - - symbolTable.insertBuiltIn(float3, "cross", float3, float3); - symbolTable.insertBuiltIn(float1, "normalize", float1); - symbolTable.insertBuiltIn(float2, "normalize", float2); - symbolTable.insertBuiltIn(float3, "normalize", float3); - symbolTable.insertBuiltIn(float4, "normalize", float4); - - symbolTable.insertBuiltIn(float1, "faceforward", float1, float1, float1); - symbolTable.insertBuiltIn(float2, "faceforward", float2, float2, float2); - symbolTable.insertBuiltIn(float3, "faceforward", float3, float3, float3); - symbolTable.insertBuiltIn(float4, "faceforward", float4, float4, float4); - - symbolTable.insertBuiltIn(float1, "reflect", float1, float1); - symbolTable.insertBuiltIn(float2, "reflect", float2, float2); - symbolTable.insertBuiltIn(float3, "reflect", float3, float3); - symbolTable.insertBuiltIn(float4, "reflect", float4, float4); - - symbolTable.insertBuiltIn(float1, "refract", float1, float1, float1); - symbolTable.insertBuiltIn(float2, "refract", float2, float2, float1); - symbolTable.insertBuiltIn(float3, "refract", float3, float3, float1); - symbolTable.insertBuiltIn(float4, "refract", float4, float4, float1); - - TType *mat2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2, true); - TType *mat3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3, true); - TType *mat4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4, true); - - // - // Matrix Functions. - // - symbolTable.insertBuiltIn(mat2, "matrixCompMult", mat2, mat2); - symbolTable.insertBuiltIn(mat3, "matrixCompMult", mat3, mat3); - symbolTable.insertBuiltIn(mat4, "matrixCompMult", mat4, mat4); - - TType *bool1 = new TType(EbtBool, EbpUndefined, EvqGlobal, 1); - TType *bool2 = new TType(EbtBool, EbpUndefined, EvqGlobal, 2); - TType *bool3 = new TType(EbtBool, EbpUndefined, EvqGlobal, 3); - TType *bool4 = new TType(EbtBool, EbpUndefined, EvqGlobal, 4); - - // - // Vector relational functions. - // - symbolTable.insertBuiltIn(bool2, "lessThan", float2, float2); - symbolTable.insertBuiltIn(bool3, "lessThan", float3, float3); - symbolTable.insertBuiltIn(bool4, "lessThan", float4, float4); - - symbolTable.insertBuiltIn(bool2, "lessThan", int2, int2); - symbolTable.insertBuiltIn(bool3, "lessThan", int3, int3); - symbolTable.insertBuiltIn(bool4, "lessThan", int4, int4); - - symbolTable.insertBuiltIn(bool2, "lessThanEqual", float2, float2); - symbolTable.insertBuiltIn(bool3, "lessThanEqual", float3, float3); - symbolTable.insertBuiltIn(bool4, "lessThanEqual", float4, float4); - - symbolTable.insertBuiltIn(bool2, "lessThanEqual", int2, int2); - symbolTable.insertBuiltIn(bool3, "lessThanEqual", int3, int3); - symbolTable.insertBuiltIn(bool4, "lessThanEqual", int4, int4); - - symbolTable.insertBuiltIn(bool2, "greaterThan", float2, float2); - symbolTable.insertBuiltIn(bool3, "greaterThan", float3, float3); - symbolTable.insertBuiltIn(bool4, "greaterThan", float4, float4); - - symbolTable.insertBuiltIn(bool2, "greaterThan", int2, int2); - symbolTable.insertBuiltIn(bool3, "greaterThan", int3, int3); - symbolTable.insertBuiltIn(bool4, "greaterThan", int4, int4); - - symbolTable.insertBuiltIn(bool2, "greaterThanEqual", float2, float2); - symbolTable.insertBuiltIn(bool3, "greaterThanEqual", float3, float3); - symbolTable.insertBuiltIn(bool4, "greaterThanEqual", float4, float4); - - symbolTable.insertBuiltIn(bool2, "greaterThanEqual", int2, int2); - symbolTable.insertBuiltIn(bool3, "greaterThanEqual", int3, int3); - symbolTable.insertBuiltIn(bool4, "greaterThanEqual", int4, int4); - - symbolTable.insertBuiltIn(bool2, "equal", float2, float2); - symbolTable.insertBuiltIn(bool3, "equal", float3, float3); - symbolTable.insertBuiltIn(bool4, "equal", float4, float4); - - symbolTable.insertBuiltIn(bool2, "equal", int2, int2); - symbolTable.insertBuiltIn(bool3, "equal", int3, int3); - symbolTable.insertBuiltIn(bool4, "equal", int4, int4); - - symbolTable.insertBuiltIn(bool2, "equal", bool2, bool2); - symbolTable.insertBuiltIn(bool3, "equal", bool3, bool3); - symbolTable.insertBuiltIn(bool4, "equal", bool4, bool4); - - symbolTable.insertBuiltIn(bool2, "notEqual", float2, float2); - symbolTable.insertBuiltIn(bool3, "notEqual", float3, float3); - symbolTable.insertBuiltIn(bool4, "notEqual", float4, float4); - - symbolTable.insertBuiltIn(bool2, "notEqual", int2, int2); - symbolTable.insertBuiltIn(bool3, "notEqual", int3, int3); - symbolTable.insertBuiltIn(bool4, "notEqual", int4, int4); - - symbolTable.insertBuiltIn(bool2, "notEqual", bool2, bool2); - symbolTable.insertBuiltIn(bool3, "notEqual", bool3, bool3); - symbolTable.insertBuiltIn(bool4, "notEqual", bool4, bool4); - - symbolTable.insertBuiltIn(bool1, "any", bool2); - symbolTable.insertBuiltIn(bool1, "any", bool3); - symbolTable.insertBuiltIn(bool1, "any", bool4); - - symbolTable.insertBuiltIn(bool1, "all", bool2); - symbolTable.insertBuiltIn(bool1, "all", bool3); - symbolTable.insertBuiltIn(bool1, "all", bool4); - - symbolTable.insertBuiltIn(bool2, "not", bool2); - symbolTable.insertBuiltIn(bool3, "not", bool3); - symbolTable.insertBuiltIn(bool4, "not", bool4); - - TType *sampler2D = new TType(EbtSampler2D, EbpUndefined, EvqGlobal, 1); - TType *samplerCube = new TType(EbtSamplerCube, EbpUndefined, EvqGlobal, 1); - - // - // Texture Functions for GLSL ES 1.0 - // - symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2); - symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3); - symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4); - symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3); - - if (resources.OES_EGL_image_external) - { - TType *samplerExternalOES = new TType(EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1); - - symbolTable.insertBuiltIn(float4, "texture2D", samplerExternalOES, float2); - symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float3); - symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float4); - } - - if (resources.ARB_texture_rectangle) - { - TType *sampler2DRect = new TType(EbtSampler2DRect, EbpUndefined, EvqGlobal, 1); - - symbolTable.insertBuiltIn(float4, "texture2DRect", sampler2DRect, float2); - symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float3); - symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float4); - } - - if (type == SH_FRAGMENT_SHADER) - { - symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2, float1); - symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3, float1); - symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4, float1); - symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3, float1); - - if (resources.OES_standard_derivatives) - { - symbolTable.insertBuiltIn(float1, "dFdx", float1); - symbolTable.insertBuiltIn(float2, "dFdx", float2); - symbolTable.insertBuiltIn(float3, "dFdx", float3); - symbolTable.insertBuiltIn(float4, "dFdx", float4); - - symbolTable.insertBuiltIn(float1, "dFdy", float1); - symbolTable.insertBuiltIn(float2, "dFdy", float2); - symbolTable.insertBuiltIn(float3, "dFdy", float3); - symbolTable.insertBuiltIn(float4, "dFdy", float4); - - symbolTable.insertBuiltIn(float1, "fwidth", float1); - symbolTable.insertBuiltIn(float2, "fwidth", float2); - symbolTable.insertBuiltIn(float3, "fwidth", float3); - symbolTable.insertBuiltIn(float4, "fwidth", float4); - } - } - - if(type == SH_VERTEX_SHADER) - { - symbolTable.insertBuiltIn(float4, "texture2DLod", sampler2D, float2, float1); - symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float3, float1); - symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, float4, float1); - symbolTable.insertBuiltIn(float4, "textureCubeLod", samplerCube, float3, float1); - } - - // - // Depth range in window coordinates - // - TFieldList *fields = NewPoolTFieldList(); - TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near")); - TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far")); - TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff")); - fields->push_back(near); - fields->push_back(far); - fields->push_back(diff); - TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields); - TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true); - symbolTable.insert(*depthRangeParameters); - TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct)); - depthRange->setQualifier(EvqUniform); - symbolTable.insert(*depthRange); - - // - // Implementation dependent built-in constants. - // - symbolTable.insertConstInt("gl_MaxVertexAttribs", resources.MaxVertexAttribs); - symbolTable.insertConstInt("gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors); - symbolTable.insertConstInt("gl_MaxVaryingVectors", resources.MaxVaryingVectors); - symbolTable.insertConstInt("gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits); - symbolTable.insertConstInt("gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits); - symbolTable.insertConstInt("gl_MaxTextureImageUnits", resources.MaxTextureImageUnits); - symbolTable.insertConstInt("gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors); - - if (spec != SH_CSS_SHADERS_SPEC) - { - symbolTable.insertConstInt("gl_MaxDrawBuffers", resources.MaxDrawBuffers); - } -} - -void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, - const ShBuiltInResources &resources, - TSymbolTable &symbolTable) -{ - // - // First, insert some special built-in variables that are not in - // the built-in header files. - // - switch(type) { - case SH_FRAGMENT_SHADER: - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); - - // - // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available. - // Instead, css_MixColor and css_ColorMatrix are available. - // - if (spec != SH_CSS_SHADERS_SPEC) { - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); - if (resources.EXT_frag_depth) { - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1))); - symbolTable.relateToExtension("gl_FragDepthEXT", "GL_EXT_frag_depth"); - } - } else { - symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, true))); - } - - break; - - case SH_VERTEX_SHADER: - symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1))); - break; - - default: assert(false && "Language not supported"); - } - - // - // Next, identify which built-ins from the already loaded headers have - // a mapping to an operator. Those that are not identified as such are - // expected to be resolved through a library of functions, versus as - // operations. - // - symbolTable.relateToOperator("matrixCompMult", EOpMul); - - symbolTable.relateToOperator("equal", EOpVectorEqual); - symbolTable.relateToOperator("notEqual", EOpVectorNotEqual); - symbolTable.relateToOperator("lessThan", EOpLessThan); - symbolTable.relateToOperator("greaterThan", EOpGreaterThan); - symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual); - symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual); - - symbolTable.relateToOperator("radians", EOpRadians); - symbolTable.relateToOperator("degrees", EOpDegrees); - symbolTable.relateToOperator("sin", EOpSin); - symbolTable.relateToOperator("cos", EOpCos); - symbolTable.relateToOperator("tan", EOpTan); - symbolTable.relateToOperator("asin", EOpAsin); - symbolTable.relateToOperator("acos", EOpAcos); - symbolTable.relateToOperator("atan", EOpAtan); - - symbolTable.relateToOperator("pow", EOpPow); - symbolTable.relateToOperator("exp2", EOpExp2); - symbolTable.relateToOperator("log", EOpLog); - symbolTable.relateToOperator("exp", EOpExp); - symbolTable.relateToOperator("log2", EOpLog2); - symbolTable.relateToOperator("sqrt", EOpSqrt); - symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt); - - symbolTable.relateToOperator("abs", EOpAbs); - symbolTable.relateToOperator("sign", EOpSign); - symbolTable.relateToOperator("floor", EOpFloor); - symbolTable.relateToOperator("ceil", EOpCeil); - symbolTable.relateToOperator("fract", EOpFract); - symbolTable.relateToOperator("mod", EOpMod); - symbolTable.relateToOperator("min", EOpMin); - symbolTable.relateToOperator("max", EOpMax); - symbolTable.relateToOperator("clamp", EOpClamp); - symbolTable.relateToOperator("mix", EOpMix); - symbolTable.relateToOperator("step", EOpStep); - symbolTable.relateToOperator("smoothstep", EOpSmoothStep); - - symbolTable.relateToOperator("length", EOpLength); - symbolTable.relateToOperator("distance", EOpDistance); - symbolTable.relateToOperator("dot", EOpDot); - symbolTable.relateToOperator("cross", EOpCross); - symbolTable.relateToOperator("normalize", EOpNormalize); - symbolTable.relateToOperator("faceforward", EOpFaceForward); - symbolTable.relateToOperator("reflect", EOpReflect); - symbolTable.relateToOperator("refract", EOpRefract); - - symbolTable.relateToOperator("any", EOpAny); - symbolTable.relateToOperator("all", EOpAll); - symbolTable.relateToOperator("not", EOpVectorLogicalNot); - - // Map language-specific operators. - switch(type) { - case SH_VERTEX_SHADER: - break; - case SH_FRAGMENT_SHADER: - if (resources.OES_standard_derivatives) { - symbolTable.relateToOperator("dFdx", EOpDFdx); - symbolTable.relateToOperator("dFdy", EOpDFdy); - symbolTable.relateToOperator("fwidth", EOpFwidth); - - symbolTable.relateToExtension("dFdx", "GL_OES_standard_derivatives"); - symbolTable.relateToExtension("dFdy", "GL_OES_standard_derivatives"); - symbolTable.relateToExtension("fwidth", "GL_OES_standard_derivatives"); - } - break; - default: break; - } - - // Finally add resource-specific variables. - switch(type) { - case SH_FRAGMENT_SHADER: - if (spec != SH_CSS_SHADERS_SPEC) { - // Set up gl_FragData. The array size. - TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, false, true); - fragData.setArraySize(resources.MaxDrawBuffers); - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); - } - break; - default: break; - } -} - -void InitExtensionBehavior(const ShBuiltInResources& resources, - TExtensionBehavior& extBehavior) -{ - if (resources.OES_standard_derivatives) - extBehavior["GL_OES_standard_derivatives"] = EBhUndefined; - if (resources.OES_EGL_image_external) - extBehavior["GL_OES_EGL_image_external"] = EBhUndefined; - if (resources.ARB_texture_rectangle) - extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined; - if (resources.EXT_draw_buffers) - extBehavior["GL_EXT_draw_buffers"] = EBhUndefined; - if (resources.EXT_frag_depth) - extBehavior["GL_EXT_frag_depth"] = EBhUndefined; -} diff --git a/chromium/third_party/angle/src/compiler/InitializeGLPosition.cpp b/chromium/third_party/angle/src/compiler/InitializeGLPosition.cpp deleted file mode 100644 index e0193e39d2e..00000000000 --- a/chromium/third_party/angle/src/compiler/InitializeGLPosition.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/InitializeGLPosition.h" -#include "compiler/debug.h" - -bool InitializeGLPosition::visitAggregate(Visit visit, TIntermAggregate* node) -{ - bool visitChildren = !mCodeInserted; - switch (node->getOp()) - { - case EOpSequence: break; - case EOpFunction: - { - // Function definition. - ASSERT(visit == PreVisit); - if (node->getName() == "main(") - { - TIntermSequence &sequence = node->getSequence(); - ASSERT((sequence.size() == 1) || (sequence.size() == 2)); - TIntermAggregate *body = NULL; - if (sequence.size() == 1) - { - body = new TIntermAggregate(EOpSequence); - sequence.push_back(body); - } - else - { - body = sequence[1]->getAsAggregate(); - } - ASSERT(body); - insertCode(body->getSequence()); - mCodeInserted = true; - } - break; - } - default: visitChildren = false; break; - } - return visitChildren; -} - -void InitializeGLPosition::insertCode(TIntermSequence& sequence) -{ - TIntermBinary *binary = new TIntermBinary(EOpAssign); - sequence.insert(sequence.begin(), binary); - - TIntermSymbol *left = new TIntermSymbol( - 0, "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4)); - binary->setLeft(left); - - ConstantUnion *u = new ConstantUnion[4]; - for (int ii = 0; ii < 3; ++ii) - u[ii].setFConst(0.0f); - u[3].setFConst(1.0f); - TIntermConstantUnion *right = new TIntermConstantUnion( - u, TType(EbtFloat, EbpUndefined, EvqConst, 4)); - binary->setRight(right); -} diff --git a/chromium/third_party/angle/src/compiler/InitializeGLPosition.h b/chromium/third_party/angle/src/compiler/InitializeGLPosition.h deleted file mode 100644 index 1b11075a137..00000000000 --- a/chromium/third_party/angle/src/compiler/InitializeGLPosition.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_INITIALIZE_GL_POSITION_H_ -#define COMPILER_INITIALIZE_GL_POSITION_H_ - -#include "compiler/intermediate.h" - -class InitializeGLPosition : public TIntermTraverser -{ -public: - InitializeGLPosition() : mCodeInserted(false) { } - -protected: - virtual bool visitBinary(Visit visit, TIntermBinary* node) { return false; } - virtual bool visitUnary(Visit visit, TIntermUnary* node) { return false; } - virtual bool visitSelection(Visit visit, TIntermSelection* node) { return false; } - virtual bool visitLoop(Visit visit, TIntermLoop* node) { return false; } - virtual bool visitBranch(Visit visit, TIntermBranch* node) { return false; } - - virtual bool visitAggregate(Visit visit, TIntermAggregate* node); - -private: - // Insert AST node in the beginning of main() for "gl_Position = vec4(0.0, 0.0, 0.0, 1.0);". - void insertCode(TIntermSequence& sequence); - - bool mCodeInserted; -}; - -#endif // COMPILER_INITIALIZE_GL_POSITION_H_ diff --git a/chromium/third_party/angle/src/compiler/MapLongVariableNames.cpp b/chromium/third_party/angle/src/compiler/MapLongVariableNames.cpp deleted file mode 100644 index 077ef5d72eb..00000000000 --- a/chromium/third_party/angle/src/compiler/MapLongVariableNames.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/MapLongVariableNames.h" - -namespace { - -TString mapLongName(size_t id, const TString& name, bool isGlobal) -{ - ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE); - TStringStream stream; - stream << "webgl_"; - if (isGlobal) - stream << "g"; - stream << id; - if (name[0] != '_') - stream << "_"; - stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size()); - return stream.str(); -} - -LongNameMap* gLongNameMapInstance = NULL; - -} // anonymous namespace - -LongNameMap::LongNameMap() - : refCount(0) -{ -} - -LongNameMap::~LongNameMap() -{ -} - -// static -LongNameMap* LongNameMap::GetInstance() -{ - if (gLongNameMapInstance == NULL) - gLongNameMapInstance = new LongNameMap; - gLongNameMapInstance->refCount++; - return gLongNameMapInstance; -} - -void LongNameMap::Release() -{ - ASSERT(gLongNameMapInstance == this); - ASSERT(refCount > 0); - refCount--; - if (refCount == 0) { - delete gLongNameMapInstance; - gLongNameMapInstance = NULL; - } -} - -const char* LongNameMap::Find(const char* originalName) const -{ - std::map<std::string, std::string>::const_iterator it = mLongNameMap.find( - originalName); - if (it != mLongNameMap.end()) - return (*it).second.c_str(); - return NULL; -} - -void LongNameMap::Insert(const char* originalName, const char* mappedName) -{ - mLongNameMap.insert(std::map<std::string, std::string>::value_type( - originalName, mappedName)); -} - -size_t LongNameMap::Size() const -{ - return mLongNameMap.size(); -} - -MapLongVariableNames::MapLongVariableNames(LongNameMap* globalMap) -{ - ASSERT(globalMap); - mGlobalMap = globalMap; -} - -void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol) -{ - ASSERT(symbol != NULL); - if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) { - switch (symbol->getQualifier()) { - case EvqVaryingIn: - case EvqVaryingOut: - case EvqInvariantVaryingIn: - case EvqInvariantVaryingOut: - case EvqUniform: - symbol->setSymbol( - mapGlobalLongName(symbol->getSymbol())); - break; - default: - symbol->setSymbol( - mapLongName(symbol->getId(), symbol->getSymbol(), false)); - break; - }; - } -} - -TString MapLongVariableNames::mapGlobalLongName(const TString& name) -{ - ASSERT(mGlobalMap); - const char* mappedName = mGlobalMap->Find(name.c_str()); - if (mappedName != NULL) - return mappedName; - size_t id = mGlobalMap->Size(); - TString rt = mapLongName(id, name, true); - mGlobalMap->Insert(name.c_str(), rt.c_str()); - return rt; -} diff --git a/chromium/third_party/angle/src/compiler/MapLongVariableNames.h b/chromium/third_party/angle/src/compiler/MapLongVariableNames.h deleted file mode 100644 index fd2ff82613c..00000000000 --- a/chromium/third_party/angle/src/compiler/MapLongVariableNames.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_MAP_LONG_VARIABLE_NAMES_H_ -#define COMPILER_MAP_LONG_VARIABLE_NAMES_H_ - -#include "GLSLANG/ShaderLang.h" - -#include "compiler/intermediate.h" -#include "compiler/VariableInfo.h" - -// This size does not include '\0' in the end. -#define MAX_SHORTENED_IDENTIFIER_SIZE 32 - -// This is a ref-counted singleton. GetInstance() returns a pointer to the -// singleton, and after use, call Release(). GetInstance() and Release() should -// be paired. -class LongNameMap { -public: - static LongNameMap* GetInstance(); - void Release(); - - // Return the mapped name if <originalName, mappedName> is in the map; - // otherwise, return NULL. - const char* Find(const char* originalName) const; - - // Insert a pair into the map. - void Insert(const char* originalName, const char* mappedName); - - // Return the number of entries in the map. - size_t Size() const; - -private: - LongNameMap(); - ~LongNameMap(); - - size_t refCount; - std::map<std::string, std::string> mLongNameMap; -}; - -// Traverses intermediate tree to map attributes and uniforms names that are -// longer than MAX_SHORTENED_IDENTIFIER_SIZE to MAX_SHORTENED_IDENTIFIER_SIZE. -class MapLongVariableNames : public TIntermTraverser { -public: - MapLongVariableNames(LongNameMap* globalMap); - - virtual void visitSymbol(TIntermSymbol*); - -private: - TString mapGlobalLongName(const TString& name); - - LongNameMap* mGlobalMap; -}; - -#endif // COMPILER_MAP_LONG_VARIABLE_NAMES_H_ diff --git a/chromium/third_party/angle/src/compiler/OutputGLSL.cpp b/chromium/third_party/angle/src/compiler/OutputGLSL.cpp deleted file mode 100644 index 10a451c0d76..00000000000 --- a/chromium/third_party/angle/src/compiler/OutputGLSL.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/OutputGLSL.h" - -TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink, - ShArrayIndexClampingStrategy clampingStrategy, - ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable) - : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable) -{ -} - -bool TOutputGLSL::writeVariablePrecision(TPrecision) -{ - return false; -} - -void TOutputGLSL::visitSymbol(TIntermSymbol* node) -{ - TInfoSinkBase& out = objSink(); - - if (node->getSymbol() == "gl_FragDepthEXT") - { - out << "gl_FragDepth"; - } - else - { - TOutputGLSLBase::visitSymbol(node); - } -} diff --git a/chromium/third_party/angle/src/compiler/OutputGLSLBase.cpp b/chromium/third_party/angle/src/compiler/OutputGLSLBase.cpp deleted file mode 100644 index b90bd67ecd7..00000000000 --- a/chromium/third_party/angle/src/compiler/OutputGLSLBase.cpp +++ /dev/null @@ -1,817 +0,0 @@ -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/OutputGLSLBase.h" -#include "compiler/debug.h" - -#include <cfloat> - -namespace -{ -TString arrayBrackets(const TType& type) -{ - ASSERT(type.isArray()); - TInfoSinkBase out; - out << "[" << type.getArraySize() << "]"; - return TString(out.c_str()); -} - -bool isSingleStatement(TIntermNode* node) { - if (const TIntermAggregate* aggregate = node->getAsAggregate()) - { - return (aggregate->getOp() != EOpFunction) && - (aggregate->getOp() != EOpSequence); - } - else if (const TIntermSelection* selection = node->getAsSelectionNode()) - { - // Ternary operators are usually part of an assignment operator. - // This handles those rare cases in which they are all by themselves. - return selection->usesTernaryOperator(); - } - else if (node->getAsLoopNode()) - { - return false; - } - return true; -} -} // namespace - -TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink, - ShArrayIndexClampingStrategy clampingStrategy, - ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable) - : TIntermTraverser(true, true, true), - mObjSink(objSink), - mDeclaringVariables(false), - mClampingStrategy(clampingStrategy), - mHashFunction(hashFunction), - mNameMap(nameMap), - mSymbolTable(symbolTable) -{ -} - -void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr) -{ - TInfoSinkBase& out = objSink(); - if (visit == PreVisit && preStr) - { - out << preStr; - } - else if (visit == InVisit && inStr) - { - out << inStr; - } - else if (visit == PostVisit && postStr) - { - out << postStr; - } -} - -void TOutputGLSLBase::writeVariableType(const TType& type) -{ - TInfoSinkBase& out = objSink(); - TQualifier qualifier = type.getQualifier(); - // TODO(alokp): Validate qualifier for variable declarations. - if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) - out << type.getQualifierString() << " "; - // Declare the struct if we have not done so already. - if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct())) - { - declareStruct(type.getStruct()); - } - else - { - if (writeVariablePrecision(type.getPrecision())) - out << " "; - out << getTypeName(type); - } -} - -void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args) -{ - TInfoSinkBase& out = objSink(); - for (TIntermSequence::const_iterator iter = args.begin(); - iter != args.end(); ++iter) - { - const TIntermSymbol* arg = (*iter)->getAsSymbolNode(); - ASSERT(arg != NULL); - - const TType& type = arg->getType(); - writeVariableType(type); - - const TString& name = arg->getSymbol(); - if (!name.empty()) - out << " " << hashName(name); - if (type.isArray()) - out << arrayBrackets(type); - - // Put a comma if this is not the last argument. - if (iter != args.end() - 1) - out << ", "; - } -} - -const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type, - const ConstantUnion* pConstUnion) -{ - TInfoSinkBase& out = objSink(); - - if (type.getBasicType() == EbtStruct) - { - const TStructure* structure = type.getStruct(); - out << hashName(structure->name()) << "("; - - const TFieldList& fields = structure->fields(); - for (size_t i = 0; i < fields.size(); ++i) - { - const TType* fieldType = fields[i]->type(); - ASSERT(fieldType != NULL); - pConstUnion = writeConstantUnion(*fieldType, pConstUnion); - if (i != fields.size() - 1) out << ", "; - } - out << ")"; - } - else - { - size_t size = type.getObjectSize(); - bool writeType = size > 1; - if (writeType) out << getTypeName(type) << "("; - for (size_t i = 0; i < size; ++i, ++pConstUnion) - { - switch (pConstUnion->getType()) - { - case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst())); break; - case EbtInt: out << pConstUnion->getIConst(); break; - case EbtBool: out << pConstUnion->getBConst(); break; - default: UNREACHABLE(); - } - if (i != size - 1) out << ", "; - } - if (writeType) out << ")"; - } - return pConstUnion; -} - -void TOutputGLSLBase::visitSymbol(TIntermSymbol* node) -{ - TInfoSinkBase& out = objSink(); - if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node)) - out << mLoopUnroll.GetLoopIndexValue(node); - else - out << hashVariableName(node->getSymbol()); - - if (mDeclaringVariables && node->getType().isArray()) - out << arrayBrackets(node->getType()); -} - -void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node) -{ - writeConstantUnion(node->getType(), node->getUnionArrayPointer()); -} - -bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node) -{ - bool visitChildren = true; - TInfoSinkBase& out = objSink(); - switch (node->getOp()) - { - case EOpInitialize: - if (visit == InVisit) - { - out << " = "; - // RHS of initialize is not being declared. - mDeclaringVariables = false; - } - break; - case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break; - case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break; - case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break; - case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break; - // Notice the fall-through. - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - writeTriplet(visit, "(", " *= ", ")"); - break; - - case EOpIndexDirect: - writeTriplet(visit, NULL, "[", "]"); - break; - case EOpIndexIndirect: - if (node->getAddIndexClamp()) - { - if (visit == InVisit) - { - if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) { - out << "[int(clamp(float("; - } else { - out << "[webgl_int_clamp("; - } - } - else if (visit == PostVisit) - { - int maxSize; - TIntermTyped *left = node->getLeft(); - TType leftType = left->getType(); - - if (left->isArray()) - { - // The shader will fail validation if the array length is not > 0. - maxSize = leftType.getArraySize() - 1; - } - else - { - maxSize = leftType.getNominalSize() - 1; - } - - if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) { - out << "), 0.0, float(" << maxSize << ")))]"; - } else { - out << ", 0, " << maxSize << ")]"; - } - } - } - else - { - writeTriplet(visit, NULL, "[", "]"); - } - break; - case EOpIndexDirectStruct: - if (visit == InVisit) - { - // Here we are writing out "foo.bar", where "foo" is struct - // and "bar" is field. In AST, it is represented as a binary - // node, where left child represents "foo" and right child "bar". - // The node itself represents ".". The struct field "bar" is - // actually stored as an index into TStructure::fields. - out << "."; - const TStructure* structure = node->getLeft()->getType().getStruct(); - const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); - const TField* field = structure->fields()[index->getIConst(0)]; - - TString fieldName = field->name(); - if (!mSymbolTable.findBuiltIn(structure->name())) - fieldName = hashName(fieldName); - - out << fieldName; - visitChildren = false; - } - break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - TIntermAggregate* rightChild = node->getRight()->getAsAggregate(); - TIntermSequence& sequence = rightChild->getSequence(); - for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit) - { - TIntermConstantUnion* element = (*sit)->getAsConstantUnion(); - ASSERT(element->getBasicType() == EbtInt); - ASSERT(element->getNominalSize() == 1); - const ConstantUnion& data = element->getUnionArrayPointer()[0]; - ASSERT(data.getType() == EbtInt); - switch (data.getIConst()) - { - case 0: out << "x"; break; - case 1: out << "y"; break; - case 2: out << "z"; break; - case 3: out << "w"; break; - default: UNREACHABLE(); break; - } - } - visitChildren = false; - } - break; - - case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break; - case EOpSub: writeTriplet(visit, "(", " - ", ")"); break; - case EOpMul: writeTriplet(visit, "(", " * ", ")"); break; - case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break; - case EOpMod: UNIMPLEMENTED(); break; - case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break; - case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break; - case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break; - case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break; - case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break; - case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break; - - // Notice the fall-through. - case EOpVectorTimesScalar: - case EOpVectorTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: - case EOpMatrixTimesMatrix: - writeTriplet(visit, "(", " * ", ")"); - break; - - case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break; - case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break; - case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break; - default: UNREACHABLE(); break; - } - - return visitChildren; -} - -bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node) -{ - TString preString; - TString postString = ")"; - - switch (node->getOp()) - { - case EOpNegative: preString = "(-"; break; - case EOpVectorLogicalNot: preString = "not("; break; - case EOpLogicalNot: preString = "(!"; break; - - case EOpPostIncrement: preString = "("; postString = "++)"; break; - case EOpPostDecrement: preString = "("; postString = "--)"; break; - case EOpPreIncrement: preString = "(++"; break; - case EOpPreDecrement: preString = "(--"; break; - - case EOpConvIntToBool: - case EOpConvFloatToBool: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: preString = "bool("; break; - case 2: preString = "bvec2("; break; - case 3: preString = "bvec3("; break; - case 4: preString = "bvec4("; break; - default: UNREACHABLE(); - } - break; - case EOpConvBoolToFloat: - case EOpConvIntToFloat: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: preString = "float("; break; - case 2: preString = "vec2("; break; - case 3: preString = "vec3("; break; - case 4: preString = "vec4("; break; - default: UNREACHABLE(); - } - break; - case EOpConvFloatToInt: - case EOpConvBoolToInt: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: preString = "int("; break; - case 2: preString = "ivec2("; break; - case 3: preString = "ivec3("; break; - case 4: preString = "ivec4("; break; - default: UNREACHABLE(); - } - break; - - case EOpRadians: preString = "radians("; break; - case EOpDegrees: preString = "degrees("; break; - case EOpSin: preString = "sin("; break; - case EOpCos: preString = "cos("; break; - case EOpTan: preString = "tan("; break; - case EOpAsin: preString = "asin("; break; - case EOpAcos: preString = "acos("; break; - case EOpAtan: preString = "atan("; break; - - case EOpExp: preString = "exp("; break; - case EOpLog: preString = "log("; break; - case EOpExp2: preString = "exp2("; break; - case EOpLog2: preString = "log2("; break; - case EOpSqrt: preString = "sqrt("; break; - case EOpInverseSqrt: preString = "inversesqrt("; break; - - case EOpAbs: preString = "abs("; break; - case EOpSign: preString = "sign("; break; - case EOpFloor: preString = "floor("; break; - case EOpCeil: preString = "ceil("; break; - case EOpFract: preString = "fract("; break; - - case EOpLength: preString = "length("; break; - case EOpNormalize: preString = "normalize("; break; - - case EOpDFdx: preString = "dFdx("; break; - case EOpDFdy: preString = "dFdy("; break; - case EOpFwidth: preString = "fwidth("; break; - - case EOpAny: preString = "any("; break; - case EOpAll: preString = "all("; break; - - default: UNREACHABLE(); break; - } - - if (visit == PreVisit && node->getUseEmulatedFunction()) - preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); - writeTriplet(visit, preString.c_str(), NULL, postString.c_str()); - - return true; -} - -bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node) -{ - TInfoSinkBase& out = objSink(); - - if (node->usesTernaryOperator()) - { - // Notice two brackets at the beginning and end. The outer ones - // encapsulate the whole ternary expression. This preserves the - // order of precedence when ternary expressions are used in a - // compound expression, i.e., c = 2 * (a < b ? 1 : 2). - out << "(("; - node->getCondition()->traverse(this); - out << ") ? ("; - node->getTrueBlock()->traverse(this); - out << ") : ("; - node->getFalseBlock()->traverse(this); - out << "))"; - } - else - { - out << "if ("; - node->getCondition()->traverse(this); - out << ")\n"; - - incrementDepth(node); - visitCodeBlock(node->getTrueBlock()); - - if (node->getFalseBlock()) - { - out << "else\n"; - visitCodeBlock(node->getFalseBlock()); - } - decrementDepth(); - } - return false; -} - -bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node) -{ - bool visitChildren = true; - TInfoSinkBase& out = objSink(); - TString preString; - bool delayedWrite = false; - switch (node->getOp()) - { - case EOpSequence: { - // Scope the sequences except when at the global scope. - if (depth > 0) out << "{\n"; - - incrementDepth(node); - const TIntermSequence& sequence = node->getSequence(); - for (TIntermSequence::const_iterator iter = sequence.begin(); - iter != sequence.end(); ++iter) - { - TIntermNode* node = *iter; - ASSERT(node != NULL); - node->traverse(this); - - if (isSingleStatement(node)) - out << ";\n"; - } - decrementDepth(); - - // Scope the sequences except when at the global scope. - if (depth > 0) out << "}\n"; - visitChildren = false; - break; - } - case EOpPrototype: { - // Function declaration. - ASSERT(visit == PreVisit); - writeVariableType(node->getType()); - out << " " << hashName(node->getName()); - - out << "("; - writeFunctionParameters(node->getSequence()); - out << ")"; - - visitChildren = false; - break; - } - case EOpFunction: { - // Function definition. - ASSERT(visit == PreVisit); - writeVariableType(node->getType()); - out << " " << hashFunctionName(node->getName()); - - incrementDepth(node); - // Function definition node contains one or two children nodes - // representing function parameters and function body. The latter - // is not present in case of empty function bodies. - const TIntermSequence& sequence = node->getSequence(); - ASSERT((sequence.size() == 1) || (sequence.size() == 2)); - TIntermSequence::const_iterator seqIter = sequence.begin(); - - // Traverse function parameters. - TIntermAggregate* params = (*seqIter)->getAsAggregate(); - ASSERT(params != NULL); - ASSERT(params->getOp() == EOpParameters); - params->traverse(this); - - // Traverse function body. - TIntermAggregate* body = ++seqIter != sequence.end() ? - (*seqIter)->getAsAggregate() : NULL; - visitCodeBlock(body); - decrementDepth(); - - // Fully processed; no need to visit children. - visitChildren = false; - break; - } - case EOpFunctionCall: - // Function call. - if (visit == PreVisit) - { - out << hashFunctionName(node->getName()) << "("; - } - else if (visit == InVisit) - { - out << ", "; - } - else - { - out << ")"; - } - break; - case EOpParameters: { - // Function parameters. - ASSERT(visit == PreVisit); - out << "("; - writeFunctionParameters(node->getSequence()); - out << ")"; - visitChildren = false; - break; - } - case EOpDeclaration: { - // Variable declaration. - if (visit == PreVisit) - { - const TIntermSequence& sequence = node->getSequence(); - const TIntermTyped* variable = sequence.front()->getAsTyped(); - writeVariableType(variable->getType()); - out << " "; - mDeclaringVariables = true; - } - else if (visit == InVisit) - { - out << ", "; - mDeclaringVariables = true; - } - else - { - mDeclaringVariables = false; - } - break; - } - case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; - case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break; - case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break; - case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break; - case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break; - case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break; - case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break; - case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break; - case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break; - case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break; - case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break; - case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break; - case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break; - case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break; - case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break; - case EOpConstructStruct: - if (visit == PreVisit) - { - const TType& type = node->getType(); - ASSERT(type.getBasicType() == EbtStruct); - out << hashName(type.getStruct()->name()) << "("; - } - else if (visit == InVisit) - { - out << ", "; - } - else - { - out << ")"; - } - break; - - case EOpLessThan: preString = "lessThan("; delayedWrite = true; break; - case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break; - case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break; - case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break; - case EOpVectorEqual: preString = "equal("; delayedWrite = true; break; - case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break; - case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break; - - case EOpMod: preString = "mod("; delayedWrite = true; break; - case EOpPow: preString = "pow("; delayedWrite = true; break; - case EOpAtan: preString = "atan("; delayedWrite = true; break; - case EOpMin: preString = "min("; delayedWrite = true; break; - case EOpMax: preString = "max("; delayedWrite = true; break; - case EOpClamp: preString = "clamp("; delayedWrite = true; break; - case EOpMix: preString = "mix("; delayedWrite = true; break; - case EOpStep: preString = "step("; delayedWrite = true; break; - case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break; - - case EOpDistance: preString = "distance("; delayedWrite = true; break; - case EOpDot: preString = "dot("; delayedWrite = true; break; - case EOpCross: preString = "cross("; delayedWrite = true; break; - case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break; - case EOpReflect: preString = "reflect("; delayedWrite = true; break; - case EOpRefract: preString = "refract("; delayedWrite = true; break; - case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break; - - default: UNREACHABLE(); break; - } - if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction()) - preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); - if (delayedWrite) - writeTriplet(visit, preString.c_str(), ", ", ")"); - return visitChildren; -} - -bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node) -{ - TInfoSinkBase& out = objSink(); - - incrementDepth(node); - // Loop header. - TLoopType loopType = node->getType(); - if (loopType == ELoopFor) // for loop - { - if (!node->getUnrollFlag()) { - out << "for ("; - if (node->getInit()) - node->getInit()->traverse(this); - out << "; "; - - if (node->getCondition()) - node->getCondition()->traverse(this); - out << "; "; - - if (node->getExpression()) - node->getExpression()->traverse(this); - out << ")\n"; - } - } - else if (loopType == ELoopWhile) // while loop - { - out << "while ("; - ASSERT(node->getCondition() != NULL); - node->getCondition()->traverse(this); - out << ")\n"; - } - else // do-while loop - { - ASSERT(loopType == ELoopDoWhile); - out << "do\n"; - } - - // Loop body. - if (node->getUnrollFlag()) - { - TLoopIndexInfo indexInfo; - mLoopUnroll.FillLoopIndexInfo(node, indexInfo); - mLoopUnroll.Push(indexInfo); - while (mLoopUnroll.SatisfiesLoopCondition()) - { - visitCodeBlock(node->getBody()); - mLoopUnroll.Step(); - } - mLoopUnroll.Pop(); - } - else - { - visitCodeBlock(node->getBody()); - } - - // Loop footer. - if (loopType == ELoopDoWhile) // do-while loop - { - out << "while ("; - ASSERT(node->getCondition() != NULL); - node->getCondition()->traverse(this); - out << ");\n"; - } - decrementDepth(); - - // No need to visit children. They have been already processed in - // this function. - return false; -} - -bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch* node) -{ - switch (node->getFlowOp()) - { - case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break; - case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break; - case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break; - case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break; - default: UNREACHABLE(); break; - } - - return true; -} - -void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) { - TInfoSinkBase &out = objSink(); - if (node != NULL) - { - node->traverse(this); - // Single statements not part of a sequence need to be terminated - // with semi-colon. - if (isSingleStatement(node)) - out << ";\n"; - } - else - { - out << "{\n}\n"; // Empty code block. - } -} - -TString TOutputGLSLBase::getTypeName(const TType& type) -{ - TInfoSinkBase out; - if (type.isMatrix()) - { - out << "mat"; - out << type.getNominalSize(); - } - else if (type.isVector()) - { - switch (type.getBasicType()) - { - case EbtFloat: out << "vec"; break; - case EbtInt: out << "ivec"; break; - case EbtBool: out << "bvec"; break; - default: UNREACHABLE(); break; - } - out << type.getNominalSize(); - } - else - { - if (type.getBasicType() == EbtStruct) - out << hashName(type.getStruct()->name()); - else - out << type.getBasicString(); - } - return TString(out.c_str()); -} - -TString TOutputGLSLBase::hashName(const TString& name) -{ - if (mHashFunction == NULL || name.empty()) - return name; - NameMap::const_iterator it = mNameMap.find(name.c_str()); - if (it != mNameMap.end()) - return it->second.c_str(); - TString hashedName = TIntermTraverser::hash(name, mHashFunction); - mNameMap[name.c_str()] = hashedName.c_str(); - return hashedName; -} - -TString TOutputGLSLBase::hashVariableName(const TString& name) -{ - if (mSymbolTable.findBuiltIn(name) != NULL) - return name; - return hashName(name); -} - -TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name) -{ - TString name = TFunction::unmangleName(mangled_name); - if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main") - return name; - return hashName(name); -} - -bool TOutputGLSLBase::structDeclared(const TStructure* structure) const -{ - return mDeclaredStructs.find(structure->name()) != mDeclaredStructs.end(); -} - -void TOutputGLSLBase::declareStruct(const TStructure* structure) -{ - TInfoSinkBase& out = objSink(); - - out << "struct " << hashName(structure->name()) << "{\n"; - const TFieldList& fields = structure->fields(); - for (size_t i = 0; i < fields.size(); ++i) - { - const TField* field = fields[i]; - if (writeVariablePrecision(field->type()->getPrecision())) - out << " "; - out << getTypeName(*field->type()) << " " << hashName(field->name()); - if (field->type()->isArray()) - out << arrayBrackets(*field->type()); - out << ";\n"; - } - out << "}"; - - mDeclaredStructs.insert(structure->name()); -} diff --git a/chromium/third_party/angle/src/compiler/OutputGLSLBase.h b/chromium/third_party/angle/src/compiler/OutputGLSLBase.h deleted file mode 100644 index 69868c09ccf..00000000000 --- a/chromium/third_party/angle/src/compiler/OutputGLSLBase.h +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ -#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ - -#include <set> - -#include "compiler/ForLoopUnroll.h" -#include "compiler/intermediate.h" -#include "compiler/ParseContext.h" - -class TOutputGLSLBase : public TIntermTraverser -{ -public: - TOutputGLSLBase(TInfoSinkBase& objSink, - ShArrayIndexClampingStrategy clampingStrategy, - ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable); - -protected: - TInfoSinkBase& objSink() { return mObjSink; } - void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr); - void writeVariableType(const TType& type); - virtual bool writeVariablePrecision(TPrecision precision) = 0; - void writeFunctionParameters(const TIntermSequence& args); - const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion); - TString getTypeName(const TType& type); - - virtual void visitSymbol(TIntermSymbol* node); - virtual void visitConstantUnion(TIntermConstantUnion* node); - virtual bool visitBinary(Visit visit, TIntermBinary* node); - virtual bool visitUnary(Visit visit, TIntermUnary* node); - virtual bool visitSelection(Visit visit, TIntermSelection* node); - virtual bool visitAggregate(Visit visit, TIntermAggregate* node); - virtual bool visitLoop(Visit visit, TIntermLoop* node); - virtual bool visitBranch(Visit visit, TIntermBranch* node); - - void visitCodeBlock(TIntermNode* node); - - - // Return the original name if hash function pointer is NULL; - // otherwise return the hashed name. - TString hashName(const TString& name); - // Same as hashName(), but without hashing built-in variables. - TString hashVariableName(const TString& name); - // Same as hashName(), but without hashing built-in functions. - TString hashFunctionName(const TString& mangled_name); - -private: - bool structDeclared(const TStructure* structure) const; - void declareStruct(const TStructure* structure); - - TInfoSinkBase& mObjSink; - bool mDeclaringVariables; - - // Structs are declared as the tree is traversed. This set contains all - // the structs already declared. It is maintained so that a struct is - // declared only once. - typedef std::set<TString> DeclaredStructs; - DeclaredStructs mDeclaredStructs; - - ForLoopUnroll mLoopUnroll; - - ShArrayIndexClampingStrategy mClampingStrategy; - - // name hashing. - ShHashFunction64 mHashFunction; - - NameMap& mNameMap; - - TSymbolTable& mSymbolTable; -}; - -#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ diff --git a/chromium/third_party/angle/src/compiler/OutputHLSL.cpp b/chromium/third_party/angle/src/compiler/OutputHLSL.cpp deleted file mode 100644 index 53799dffe76..00000000000 --- a/chromium/third_party/angle/src/compiler/OutputHLSL.cpp +++ /dev/null @@ -1,3133 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/OutputHLSL.h" - -#include "common/angleutils.h" -#include "compiler/debug.h" -#include "compiler/DetectDiscontinuity.h" -#include "compiler/InfoSink.h" -#include "compiler/SearchSymbol.h" -#include "compiler/UnfoldShortCircuit.h" -#include "compiler/NodeSearch.h" - -#include <algorithm> -#include <cfloat> -#include <stdio.h> - -namespace sh -{ -// Integer to TString conversion -TString str(int i) -{ - char buffer[20]; - snprintf(buffer, sizeof(buffer), "%d", i); - return buffer; -} - -OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType) - : TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType) -{ - mUnfoldShortCircuit = new UnfoldShortCircuit(context, this); - mInsideFunction = false; - - mUsesTexture2D = false; - mUsesTexture2D_bias = false; - mUsesTexture2DProj = false; - mUsesTexture2DProj_bias = false; - mUsesTexture2DProjLod = false; - mUsesTexture2DLod = false; - mUsesTextureCube = false; - mUsesTextureCube_bias = false; - mUsesTextureCubeLod = false; - mUsesTexture2DLod0 = false; - mUsesTexture2DLod0_bias = false; - mUsesTexture2DProjLod0 = false; - mUsesTexture2DProjLod0_bias = false; - mUsesTextureCubeLod0 = false; - mUsesTextureCubeLod0_bias = false; - mUsesFragColor = false; - mUsesFragData = false; - mUsesDepthRange = false; - mUsesFragCoord = false; - mUsesPointCoord = false; - mUsesFrontFacing = false; - mUsesPointSize = false; - mUsesFragDepth = false; - mUsesXor = false; - mUsesMod1 = false; - mUsesMod2v = false; - mUsesMod2f = false; - mUsesMod3v = false; - mUsesMod3f = false; - mUsesMod4v = false; - mUsesMod4f = false; - mUsesFaceforward1 = false; - mUsesFaceforward2 = false; - mUsesFaceforward3 = false; - mUsesFaceforward4 = false; - mUsesAtan2_1 = false; - mUsesAtan2_2 = false; - mUsesAtan2_3 = false; - mUsesAtan2_4 = false; - mUsesDiscardRewriting = false; - - mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; - - mScopeDepth = 0; - - mUniqueIndex = 0; - - mContainsLoopDiscontinuity = false; - mOutputLod0Function = false; - mInsideDiscontinuousLoop = false; - - mExcessiveLoopIndex = NULL; - - if (mOutputType == SH_HLSL9_OUTPUT) - { - if (mContext.shaderType == SH_FRAGMENT_SHADER) - { - mUniformRegister = 3; // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront - } - else - { - mUniformRegister = 2; // Reserve registers for dx_DepthRange and dx_ViewAdjust - } - } - else - { - mUniformRegister = 0; - } - - mSamplerRegister = 0; -} - -OutputHLSL::~OutputHLSL() -{ - delete mUnfoldShortCircuit; -} - -void OutputHLSL::output() -{ - mContainsLoopDiscontinuity = mContext.shaderType == SH_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot); - - mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header - header(); - - mContext.infoSink().obj << mHeader.c_str(); - mContext.infoSink().obj << mBody.c_str(); -} - -TInfoSinkBase &OutputHLSL::getBodyStream() -{ - return mBody; -} - -const ActiveUniforms &OutputHLSL::getUniforms() -{ - return mActiveUniforms; -} - -int OutputHLSL::vectorSize(const TType &type) const -{ - int elementSize = type.isMatrix() ? type.getNominalSize() : 1; - int arraySize = type.isArray() ? type.getArraySize() : 1; - - return elementSize * arraySize; -} - -void OutputHLSL::header() -{ - ShShaderType shaderType = mContext.shaderType; - TInfoSinkBase &out = mHeader; - - for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++) - { - out << *structDeclaration; - } - - for (Constructors::iterator constructor = mConstructors.begin(); constructor != mConstructors.end(); constructor++) - { - out << *constructor; - } - - TString uniforms; - TString varyings; - TString attributes; - - for (ReferencedSymbols::const_iterator uniform = mReferencedUniforms.begin(); uniform != mReferencedUniforms.end(); uniform++) - { - const TType &type = uniform->second->getType(); - const TString &name = uniform->second->getSymbol(); - - if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture - { - int index = samplerRegister(mReferencedUniforms[name]); - - uniforms += "uniform SamplerState sampler_" + decorateUniform(name, type) + arrayString(type) + - " : register(s" + str(index) + ");\n"; - - uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) + - " : register(t" + str(index) + ");\n"; - } - else - { - uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) + - " : register(" + registerString(mReferencedUniforms[name]) + ");\n"; - } - } - - for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++) - { - const TType &type = varying->second->getType(); - const TString &name = varying->second->getSymbol(); - - // Program linking depends on this exact format - varyings += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n"; - } - - for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++) - { - const TType &type = attribute->second->getType(); - const TString &name = attribute->second->getSymbol(); - - attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n"; - } - - if (mUsesDiscardRewriting) - { - out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n"; - } - - if (shaderType == SH_FRAGMENT_SHADER) - { - TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers"); - const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire)); - - const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1; - - out << "// Varyings\n"; - out << varyings; - out << "\n" - "static float4 gl_Color[" << numColorValues << "] =\n" - "{\n"; - for (unsigned int i = 0; i < numColorValues; i++) - { - out << " float4(0, 0, 0, 0)"; - if (i + 1 != numColorValues) - { - out << ","; - } - out << "\n"; - } - out << "};\n"; - - if (mUsesFragDepth) - { - out << "static float gl_Depth = 0.0;\n"; - } - - if (mUsesFragCoord) - { - out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n"; - } - - if (mUsesPointCoord) - { - out << "static float2 gl_PointCoord = float2(0.5, 0.5);\n"; - } - - if (mUsesFrontFacing) - { - out << "static bool gl_FrontFacing = false;\n"; - } - - out << "\n"; - - if (mUsesDepthRange) - { - out << "struct gl_DepthRangeParameters\n" - "{\n" - " float near;\n" - " float far;\n" - " float diff;\n" - "};\n" - "\n"; - } - - if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "cbuffer DriverConstants : register(b1)\n" - "{\n"; - - if (mUsesDepthRange) - { - out << " float3 dx_DepthRange : packoffset(c0);\n"; - } - - if (mUsesFragCoord) - { - out << " float4 dx_ViewCoords : packoffset(c1);\n"; - } - - if (mUsesFragCoord || mUsesFrontFacing) - { - out << " float3 dx_DepthFront : packoffset(c2);\n"; - } - - out << "};\n"; - } - else - { - if (mUsesDepthRange) - { - out << "uniform float3 dx_DepthRange : register(c0);"; - } - - if (mUsesFragCoord) - { - out << "uniform float4 dx_ViewCoords : register(c1);\n"; - } - - if (mUsesFragCoord || mUsesFrontFacing) - { - out << "uniform float3 dx_DepthFront : register(c2);\n"; - } - } - - out << "\n"; - - if (mUsesDepthRange) - { - out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" - "\n"; - } - - out << uniforms; - out << "\n"; - - if (mUsesTexture2D) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2D(sampler2D s, float2 t)\n" - "{\n" - " return tex2D(s, t);\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n" - "{\n" - " return t.Sample(s, uv);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2D_bias) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n" - "{\n" - " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv, float bias)\n" - "{\n" - " return t.SampleBias(s, uv, bias);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DProj) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" - "{\n" - " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n" - "}\n" - "\n" - "float4 gl_texture2DProj(sampler2D s, float4 t)\n" - "{\n" - " return tex2Dproj(s, t);\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n" - "{\n" - " return t.Sample(s, float2(uvw.x / uvw.z, uvw.y / uvw.z));\n" - "}\n" - "\n" - "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n" - "{\n" - " return t.Sample(s, float2(uvw.x / uvw.w, uvw.y / uvw.w));\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DProj_bias) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n" - "{\n" - " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n" - "}\n" - "\n" - "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n" - "{\n" - " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float bias)\n" - "{\n" - " return t.SampleBias(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), bias);\n" - "}\n" - "\n" - "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw, float bias)\n" - "{\n" - " return t.SampleBias(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), bias);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTextureCube) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" - "{\n" - " return texCUBE(s, t);\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n" - "{\n" - " return t.Sample(s, uvw);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTextureCube_bias) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n" - "{\n" - " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw, float bias)\n" - "{\n" - " return t.SampleBias(s, uvw, bias);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - // These *Lod0 intrinsics are not available in GL fragment shaders. - // They are used to sample using discontinuous texture coordinates. - if (mUsesTexture2DLod0) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n" - "{\n" - " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv)\n" - "{\n" - " return t.SampleLevel(s, uv, 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DLod0_bias) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n" - "{\n" - " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv, float bias)\n" - "{\n" - " return t.SampleLevel(s, uv, 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DProjLod0) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n" - "}\n" - "\n" - "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float3 uvw)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n" - "}\n" - "\n" - "float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float4 uvw)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DProjLod0_bias) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n" - "}\n" - "\n" - "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float3 uvw, float bias)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n" - "}\n" - "\n" - "float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float4 uvw, float bias)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTextureCubeLod0) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n" - "{\n" - " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw)\n" - "{\n" - " return t.SampleLevel(s, uvw, 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTextureCubeLod0_bias) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n" - "{\n" - " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw, float bias)\n" - "{\n" - " return t.SampleLevel(s, uvw, 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (usingMRTExtension && mNumRenderTargets > 1) - { - out << "#define GL_USES_MRT\n"; - } - - if (mUsesFragColor) - { - out << "#define GL_USES_FRAG_COLOR\n"; - } - - if (mUsesFragData) - { - out << "#define GL_USES_FRAG_DATA\n"; - } - } - else // Vertex shader - { - out << "// Attributes\n"; - out << attributes; - out << "\n" - "static float4 gl_Position = float4(0, 0, 0, 0);\n"; - - if (mUsesPointSize) - { - out << "static float gl_PointSize = float(1);\n"; - } - - out << "\n" - "// Varyings\n"; - out << varyings; - out << "\n"; - - if (mUsesDepthRange) - { - out << "struct gl_DepthRangeParameters\n" - "{\n" - " float near;\n" - " float far;\n" - " float diff;\n" - "};\n" - "\n"; - } - - if (mOutputType == SH_HLSL11_OUTPUT) - { - if (mUsesDepthRange) - { - out << "cbuffer DriverConstants : register(b1)\n" - "{\n" - " float3 dx_DepthRange : packoffset(c0);\n" - "};\n" - "\n"; - } - } - else - { - if (mUsesDepthRange) - { - out << "uniform float3 dx_DepthRange : register(c0);\n"; - } - - out << "uniform float4 dx_ViewAdjust : register(c1);\n" - "\n"; - } - - if (mUsesDepthRange) - { - out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" - "\n"; - } - - out << uniforms; - out << "\n"; - - if (mUsesTexture2D) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2D(sampler2D s, float2 t)\n" - "{\n" - " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n" - "{\n" - " return t.SampleLevel(s, uv, 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DLod) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n" - "{\n" - " return tex2Dlod(s, float4(t.x, t.y, 0, lod));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DLod(Texture2D t, SamplerState s, float2 uv, float lod)\n" - "{\n" - " return t.SampleLevel(s, uv, lod);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DProj) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n" - "}\n" - "\n" - "float4 gl_texture2DProj(sampler2D s, float4 t)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n" - "}\n" - "\n" - "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTexture2DProjLod) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, lod));\n" - "}\n" - "\n" - "float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n" - "{\n" - " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, lod));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float lod)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), lod);\n" - "}\n" - "\n" - "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n" - "{\n" - " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), lod);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTextureCube) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" - "{\n" - " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n" - "{\n" - " return t.SampleLevel(s, uvw, 0);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - - if (mUsesTextureCubeLod) - { - if (mOutputType == SH_HLSL9_OUTPUT) - { - out << "float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n" - "{\n" - " return texCUBElod(s, float4(t.x, t.y, t.z, lod));\n" - "}\n" - "\n"; - } - else if (mOutputType == SH_HLSL11_OUTPUT) - { - out << "float4 gl_textureCubeLod(TextureCube t, SamplerState s, float3 uvw, float lod)\n" - "{\n" - " return t.SampleLevel(s, uvw, lod);\n" - "}\n" - "\n"; - } - else UNREACHABLE(); - } - } - - if (mUsesFragCoord) - { - out << "#define GL_USES_FRAG_COORD\n"; - } - - if (mUsesPointCoord) - { - out << "#define GL_USES_POINT_COORD\n"; - } - - if (mUsesFrontFacing) - { - out << "#define GL_USES_FRONT_FACING\n"; - } - - if (mUsesPointSize) - { - out << "#define GL_USES_POINT_SIZE\n"; - } - - if (mUsesFragDepth) - { - out << "#define GL_USES_FRAG_DEPTH\n"; - } - - if (mUsesDepthRange) - { - out << "#define GL_USES_DEPTH_RANGE\n"; - } - - if (mUsesXor) - { - out << "bool xor(bool p, bool q)\n" - "{\n" - " return (p || q) && !(p && q);\n" - "}\n" - "\n"; - } - - if (mUsesMod1) - { - out << "float mod(float x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesMod2v) - { - out << "float2 mod(float2 x, float2 y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesMod2f) - { - out << "float2 mod(float2 x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesMod3v) - { - out << "float3 mod(float3 x, float3 y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesMod3f) - { - out << "float3 mod(float3 x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesMod4v) - { - out << "float4 mod(float4 x, float4 y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesMod4f) - { - out << "float4 mod(float4 x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"; - } - - if (mUsesFaceforward1) - { - out << "float faceforward(float N, float I, float Nref)\n" - "{\n" - " if(dot(Nref, I) >= 0)\n" - " {\n" - " return -N;\n" - " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"; - } - - if (mUsesFaceforward2) - { - out << "float2 faceforward(float2 N, float2 I, float2 Nref)\n" - "{\n" - " if(dot(Nref, I) >= 0)\n" - " {\n" - " return -N;\n" - " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"; - } - - if (mUsesFaceforward3) - { - out << "float3 faceforward(float3 N, float3 I, float3 Nref)\n" - "{\n" - " if(dot(Nref, I) >= 0)\n" - " {\n" - " return -N;\n" - " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"; - } - - if (mUsesFaceforward4) - { - out << "float4 faceforward(float4 N, float4 I, float4 Nref)\n" - "{\n" - " if(dot(Nref, I) >= 0)\n" - " {\n" - " return -N;\n" - " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"; - } - - if (mUsesAtan2_1) - { - out << "float atanyx(float y, float x)\n" - "{\n" - " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN - " return atan2(y, x);\n" - "}\n"; - } - - if (mUsesAtan2_2) - { - out << "float2 atanyx(float2 y, float2 x)\n" - "{\n" - " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" - " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" - " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n" - "}\n"; - } - - if (mUsesAtan2_3) - { - out << "float3 atanyx(float3 y, float3 x)\n" - "{\n" - " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" - " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" - " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" - " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n" - "}\n"; - } - - if (mUsesAtan2_4) - { - out << "float4 atanyx(float4 y, float4 x)\n" - "{\n" - " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" - " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" - " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" - " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n" - " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n" - "}\n"; - } -} - -void OutputHLSL::visitSymbol(TIntermSymbol *node) -{ - TInfoSinkBase &out = mBody; - - TString name = node->getSymbol(); - - if (name == "gl_FragColor") - { - out << "gl_Color[0]"; - mUsesFragColor = true; - } - else if (name == "gl_FragData") - { - out << "gl_Color"; - mUsesFragData = true; - } - else if (name == "gl_DepthRange") - { - mUsesDepthRange = true; - out << name; - } - else if (name == "gl_FragCoord") - { - mUsesFragCoord = true; - out << name; - } - else if (name == "gl_PointCoord") - { - mUsesPointCoord = true; - out << name; - } - else if (name == "gl_FrontFacing") - { - mUsesFrontFacing = true; - out << name; - } - else if (name == "gl_PointSize") - { - mUsesPointSize = true; - out << name; - } - else if (name == "gl_FragDepthEXT") - { - mUsesFragDepth = true; - out << "gl_Depth"; - } - else - { - TQualifier qualifier = node->getQualifier(); - - if (qualifier == EvqUniform) - { - mReferencedUniforms[name] = node; - out << decorateUniform(name, node->getType()); - } - else if (qualifier == EvqAttribute) - { - mReferencedAttributes[name] = node; - out << decorate(name); - } - else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn) - { - mReferencedVaryings[name] = node; - out << decorate(name); - } - else - { - out << decorate(name); - } - } -} - -bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) -{ - TInfoSinkBase &out = mBody; - - switch (node->getOp()) - { - case EOpAssign: outputTriplet(visit, "(", " = ", ")"); break; - case EOpInitialize: - if (visit == PreVisit) - { - // GLSL allows to write things like "float x = x;" where a new variable x is defined - // and the value of an existing variable x is assigned. HLSL uses C semantics (the - // new variable is created before the assignment is evaluated), so we need to convert - // this to "float t = x, x = t;". - - TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode(); - TIntermTyped *expression = node->getRight(); - - sh::SearchSymbol searchSymbol(symbolNode->getSymbol()); - expression->traverse(&searchSymbol); - bool sameSymbol = searchSymbol.foundMatch(); - - if (sameSymbol) - { - // Type already printed - out << "t" + str(mUniqueIndex) + " = "; - expression->traverse(this); - out << ", "; - symbolNode->traverse(this); - out << " = t" + str(mUniqueIndex); - - mUniqueIndex++; - return false; - } - } - else if (visit == InVisit) - { - out << " = "; - } - break; - case EOpAddAssign: outputTriplet(visit, "(", " += ", ")"); break; - case EOpSubAssign: outputTriplet(visit, "(", " -= ", ")"); break; - case EOpMulAssign: outputTriplet(visit, "(", " *= ", ")"); break; - case EOpVectorTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break; - case EOpMatrixTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break; - case EOpVectorTimesMatrixAssign: - if (visit == PreVisit) - { - out << "("; - } - else if (visit == InVisit) - { - out << " = mul("; - node->getLeft()->traverse(this); - out << ", transpose("; - } - else - { - out << ")))"; - } - break; - case EOpMatrixTimesMatrixAssign: - if (visit == PreVisit) - { - out << "("; - } - else if (visit == InVisit) - { - out << " = mul("; - node->getLeft()->traverse(this); - out << ", "; - } - else - { - out << "))"; - } - break; - case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break; - case EOpIndexDirect: outputTriplet(visit, "", "[", "]"); break; - case EOpIndexIndirect: outputTriplet(visit, "", "[", "]"); break; - case EOpIndexDirectStruct: - if (visit == InVisit) - { - const TStructure* structure = node->getLeft()->getType().getStruct(); - const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); - const TField* field = structure->fields()[index->getIConst(0)]; - out << "." + decorateField(field->name(), node->getLeft()->getType()); - - return false; - } - break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - - TIntermAggregate *swizzle = node->getRight()->getAsAggregate(); - - if (swizzle) - { - TIntermSequence &sequence = swizzle->getSequence(); - - for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) - { - TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); - - if (element) - { - int i = element->getIConst(0); - - switch (i) - { - case 0: out << "x"; break; - case 1: out << "y"; break; - case 2: out << "z"; break; - case 3: out << "w"; break; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - } - } - else UNREACHABLE(); - - return false; // Fully processed - } - break; - case EOpAdd: outputTriplet(visit, "(", " + ", ")"); break; - case EOpSub: outputTriplet(visit, "(", " - ", ")"); break; - case EOpMul: outputTriplet(visit, "(", " * ", ")"); break; - case EOpDiv: outputTriplet(visit, "(", " / ", ")"); break; - case EOpEqual: - case EOpNotEqual: - if (node->getLeft()->isScalar()) - { - if (node->getOp() == EOpEqual) - { - outputTriplet(visit, "(", " == ", ")"); - } - else - { - outputTriplet(visit, "(", " != ", ")"); - } - } - else if (node->getLeft()->getBasicType() == EbtStruct) - { - if (node->getOp() == EOpEqual) - { - out << "("; - } - else - { - out << "!("; - } - - const TFieldList &fields = node->getLeft()->getType().getStruct()->fields(); - - for (size_t i = 0; i < fields.size(); i++) - { - const TField *field = fields[i]; - - node->getLeft()->traverse(this); - out << "." + decorateField(field->name(), node->getLeft()->getType()) + " == "; - node->getRight()->traverse(this); - out << "." + decorateField(field->name(), node->getLeft()->getType()); - - if (i < fields.size() - 1) - { - out << " && "; - } - } - - out << ")"; - - return false; - } - else - { - ASSERT(node->getLeft()->isMatrix() || node->getLeft()->isVector()); - - if (node->getOp() == EOpEqual) - { - outputTriplet(visit, "all(", " == ", ")"); - } - else - { - outputTriplet(visit, "!all(", " == ", ")"); - } - } - break; - case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; - case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; - case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break; - case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break; - case EOpVectorTimesScalar: outputTriplet(visit, "(", " * ", ")"); break; - case EOpMatrixTimesScalar: outputTriplet(visit, "(", " * ", ")"); break; - case EOpVectorTimesMatrix: outputTriplet(visit, "mul(", ", transpose(", "))"); break; - case EOpMatrixTimesVector: outputTriplet(visit, "mul(transpose(", "), ", ")"); break; - case EOpMatrixTimesMatrix: outputTriplet(visit, "transpose(mul(transpose(", "), transpose(", ")))"); break; - case EOpLogicalOr: - if (node->getRight()->hasSideEffects()) - { - out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); - return false; - } - else - { - outputTriplet(visit, "(", " || ", ")"); - return true; - } - case EOpLogicalXor: - mUsesXor = true; - outputTriplet(visit, "xor(", ", ", ")"); - break; - case EOpLogicalAnd: - if (node->getRight()->hasSideEffects()) - { - out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); - return false; - } - else - { - outputTriplet(visit, "(", " && ", ")"); - return true; - } - default: UNREACHABLE(); - } - - return true; -} - -bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) -{ - switch (node->getOp()) - { - case EOpNegative: outputTriplet(visit, "(-", "", ")"); break; - case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break; - case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break; - case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break; - case EOpPostDecrement: outputTriplet(visit, "(", "", "--)"); break; - case EOpPreIncrement: outputTriplet(visit, "(++", "", ")"); break; - case EOpPreDecrement: outputTriplet(visit, "(--", "", ")"); break; - case EOpConvIntToBool: - case EOpConvFloatToBool: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: outputTriplet(visit, "bool(", "", ")"); break; - case 2: outputTriplet(visit, "bool2(", "", ")"); break; - case 3: outputTriplet(visit, "bool3(", "", ")"); break; - case 4: outputTriplet(visit, "bool4(", "", ")"); break; - default: UNREACHABLE(); - } - break; - case EOpConvBoolToFloat: - case EOpConvIntToFloat: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: outputTriplet(visit, "float(", "", ")"); break; - case 2: outputTriplet(visit, "float2(", "", ")"); break; - case 3: outputTriplet(visit, "float3(", "", ")"); break; - case 4: outputTriplet(visit, "float4(", "", ")"); break; - default: UNREACHABLE(); - } - break; - case EOpConvFloatToInt: - case EOpConvBoolToInt: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: outputTriplet(visit, "int(", "", ")"); break; - case 2: outputTriplet(visit, "int2(", "", ")"); break; - case 3: outputTriplet(visit, "int3(", "", ")"); break; - case 4: outputTriplet(visit, "int4(", "", ")"); break; - default: UNREACHABLE(); - } - break; - case EOpRadians: outputTriplet(visit, "radians(", "", ")"); break; - case EOpDegrees: outputTriplet(visit, "degrees(", "", ")"); break; - case EOpSin: outputTriplet(visit, "sin(", "", ")"); break; - case EOpCos: outputTriplet(visit, "cos(", "", ")"); break; - case EOpTan: outputTriplet(visit, "tan(", "", ")"); break; - case EOpAsin: outputTriplet(visit, "asin(", "", ")"); break; - case EOpAcos: outputTriplet(visit, "acos(", "", ")"); break; - case EOpAtan: outputTriplet(visit, "atan(", "", ")"); break; - case EOpExp: outputTriplet(visit, "exp(", "", ")"); break; - case EOpLog: outputTriplet(visit, "log(", "", ")"); break; - case EOpExp2: outputTriplet(visit, "exp2(", "", ")"); break; - case EOpLog2: outputTriplet(visit, "log2(", "", ")"); break; - case EOpSqrt: outputTriplet(visit, "sqrt(", "", ")"); break; - case EOpInverseSqrt: outputTriplet(visit, "rsqrt(", "", ")"); break; - case EOpAbs: outputTriplet(visit, "abs(", "", ")"); break; - case EOpSign: outputTriplet(visit, "sign(", "", ")"); break; - case EOpFloor: outputTriplet(visit, "floor(", "", ")"); break; - case EOpCeil: outputTriplet(visit, "ceil(", "", ")"); break; - case EOpFract: outputTriplet(visit, "frac(", "", ")"); break; - case EOpLength: outputTriplet(visit, "length(", "", ")"); break; - case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break; - case EOpDFdx: - if(mInsideDiscontinuousLoop || mOutputLod0Function) - { - outputTriplet(visit, "(", "", ", 0.0)"); - } - else - { - outputTriplet(visit, "ddx(", "", ")"); - } - break; - case EOpDFdy: - if(mInsideDiscontinuousLoop || mOutputLod0Function) - { - outputTriplet(visit, "(", "", ", 0.0)"); - } - else - { - outputTriplet(visit, "ddy(", "", ")"); - } - break; - case EOpFwidth: - if(mInsideDiscontinuousLoop || mOutputLod0Function) - { - outputTriplet(visit, "(", "", ", 0.0)"); - } - else - { - outputTriplet(visit, "fwidth(", "", ")"); - } - break; - case EOpAny: outputTriplet(visit, "any(", "", ")"); break; - case EOpAll: outputTriplet(visit, "all(", "", ")"); break; - default: UNREACHABLE(); - } - - return true; -} - -bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) -{ - TInfoSinkBase &out = mBody; - - switch (node->getOp()) - { - case EOpSequence: - { - if (mInsideFunction) - { - outputLineDirective(node->getLine().first_line); - out << "{\n"; - - mScopeDepth++; - - if (mScopeBracket.size() < mScopeDepth) - { - mScopeBracket.push_back(0); // New scope level - } - else - { - mScopeBracket[mScopeDepth - 1]++; // New scope at existing level - } - } - - for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++) - { - outputLineDirective((*sit)->getLine().first_line); - - traverseStatements(*sit); - - out << ";\n"; - } - - if (mInsideFunction) - { - outputLineDirective(node->getLine().last_line); - out << "}\n"; - - mScopeDepth--; - } - - return false; - } - case EOpDeclaration: - if (visit == PreVisit) - { - TIntermSequence &sequence = node->getSequence(); - TIntermTyped *variable = sequence[0]->getAsTyped(); - - if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal)) - { - if (variable->getType().getStruct()) - { - addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL); - } - - if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration - { - if (!mInsideFunction) - { - out << "static "; - } - - out << typeString(variable->getType()) + " "; - - for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) - { - TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); - - if (symbol) - { - symbol->traverse(this); - out << arrayString(symbol->getType()); - out << " = " + initializer(variable->getType()); - } - else - { - (*sit)->traverse(this); - } - - if (*sit != sequence.back()) - { - out << ", "; - } - } - } - else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration - { - // Already added to constructor map - } - else UNREACHABLE(); - } - else if (variable && (variable->getQualifier() == EvqVaryingOut || variable->getQualifier() == EvqInvariantVaryingOut)) - { - for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) - { - TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); - - if (symbol) - { - // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking - mReferencedVaryings[symbol->getSymbol()] = symbol; - } - else - { - (*sit)->traverse(this); - } - } - } - - return false; - } - else if (visit == InVisit) - { - out << ", "; - } - break; - case EOpPrototype: - if (visit == PreVisit) - { - out << typeString(node->getType()) << " " << decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "("); - - TIntermSequence &arguments = node->getSequence(); - - for (unsigned int i = 0; i < arguments.size(); i++) - { - TIntermSymbol *symbol = arguments[i]->getAsSymbolNode(); - - if (symbol) - { - out << argumentString(symbol); - - if (i < arguments.size() - 1) - { - out << ", "; - } - } - else UNREACHABLE(); - } - - out << ");\n"; - - // Also prototype the Lod0 variant if needed - if (mContainsLoopDiscontinuity && !mOutputLod0Function) - { - mOutputLod0Function = true; - node->traverse(this); - mOutputLod0Function = false; - } - - return false; - } - break; - case EOpComma: outputTriplet(visit, "(", ", ", ")"); break; - case EOpFunction: - { - TString name = TFunction::unmangleName(node->getName()); - - out << typeString(node->getType()) << " "; - - if (name == "main") - { - out << "gl_main("; - } - else - { - out << decorate(name) << (mOutputLod0Function ? "Lod0(" : "("); - } - - TIntermSequence &sequence = node->getSequence(); - TIntermSequence &arguments = sequence[0]->getAsAggregate()->getSequence(); - - for (unsigned int i = 0; i < arguments.size(); i++) - { - TIntermSymbol *symbol = arguments[i]->getAsSymbolNode(); - - if (symbol) - { - if (symbol->getType().getStruct()) - { - addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL); - } - - out << argumentString(symbol); - - if (i < arguments.size() - 1) - { - out << ", "; - } - } - else UNREACHABLE(); - } - - out << ")\n" - "{\n"; - - if (sequence.size() > 1) - { - mInsideFunction = true; - sequence[1]->traverse(this); - mInsideFunction = false; - } - - out << "}\n"; - - if (mContainsLoopDiscontinuity && !mOutputLod0Function) - { - if (name != "main") - { - mOutputLod0Function = true; - node->traverse(this); - mOutputLod0Function = false; - } - } - - return false; - } - break; - case EOpFunctionCall: - { - TString name = TFunction::unmangleName(node->getName()); - bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function; - - if (node->isUserDefined()) - { - out << decorate(name) << (lod0 ? "Lod0(" : "("); - } - else - { - if (name == "texture2D") - { - if (!lod0) - { - if (node->getSequence().size() == 2) - { - mUsesTexture2D = true; - } - else if (node->getSequence().size() == 3) - { - mUsesTexture2D_bias = true; - } - else UNREACHABLE(); - - out << "gl_texture2D("; - } - else - { - if (node->getSequence().size() == 2) - { - mUsesTexture2DLod0 = true; - } - else if (node->getSequence().size() == 3) - { - mUsesTexture2DLod0_bias = true; - } - else UNREACHABLE(); - - out << "gl_texture2DLod0("; - } - } - else if (name == "texture2DProj") - { - if (!lod0) - { - if (node->getSequence().size() == 2) - { - mUsesTexture2DProj = true; - } - else if (node->getSequence().size() == 3) - { - mUsesTexture2DProj_bias = true; - } - else UNREACHABLE(); - - out << "gl_texture2DProj("; - } - else - { - if (node->getSequence().size() == 2) - { - mUsesTexture2DProjLod0 = true; - } - else if (node->getSequence().size() == 3) - { - mUsesTexture2DProjLod0_bias = true; - } - else UNREACHABLE(); - - out << "gl_texture2DProjLod0("; - } - } - else if (name == "textureCube") - { - if (!lod0) - { - if (node->getSequence().size() == 2) - { - mUsesTextureCube = true; - } - else if (node->getSequence().size() == 3) - { - mUsesTextureCube_bias = true; - } - else UNREACHABLE(); - - out << "gl_textureCube("; - } - else - { - if (node->getSequence().size() == 2) - { - mUsesTextureCubeLod0 = true; - } - else if (node->getSequence().size() == 3) - { - mUsesTextureCubeLod0_bias = true; - } - else UNREACHABLE(); - - out << "gl_textureCubeLod0("; - } - } - else if (name == "texture2DLod") - { - if (node->getSequence().size() == 3) - { - mUsesTexture2DLod = true; - } - else UNREACHABLE(); - - out << "gl_texture2DLod("; - } - else if (name == "texture2DProjLod") - { - if (node->getSequence().size() == 3) - { - mUsesTexture2DProjLod = true; - } - else UNREACHABLE(); - - out << "gl_texture2DProjLod("; - } - else if (name == "textureCubeLod") - { - if (node->getSequence().size() == 3) - { - mUsesTextureCubeLod = true; - } - else UNREACHABLE(); - - out << "gl_textureCubeLod("; - } - else UNREACHABLE(); - } - - TIntermSequence &arguments = node->getSequence(); - - for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++) - { - if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType())) - { - out << "texture_"; - (*arg)->traverse(this); - out << ", sampler_"; - } - - (*arg)->traverse(this); - - if (arg < arguments.end() - 1) - { - out << ", "; - } - } - - out << ")"; - - return false; - } - break; - case EOpParameters: outputTriplet(visit, "(", ", ", ")\n{\n"); break; - case EOpConstructFloat: - addConstructor(node->getType(), "vec1", &node->getSequence()); - outputTriplet(visit, "vec1(", "", ")"); - break; - case EOpConstructVec2: - addConstructor(node->getType(), "vec2", &node->getSequence()); - outputTriplet(visit, "vec2(", ", ", ")"); - break; - case EOpConstructVec3: - addConstructor(node->getType(), "vec3", &node->getSequence()); - outputTriplet(visit, "vec3(", ", ", ")"); - break; - case EOpConstructVec4: - addConstructor(node->getType(), "vec4", &node->getSequence()); - outputTriplet(visit, "vec4(", ", ", ")"); - break; - case EOpConstructBool: - addConstructor(node->getType(), "bvec1", &node->getSequence()); - outputTriplet(visit, "bvec1(", "", ")"); - break; - case EOpConstructBVec2: - addConstructor(node->getType(), "bvec2", &node->getSequence()); - outputTriplet(visit, "bvec2(", ", ", ")"); - break; - case EOpConstructBVec3: - addConstructor(node->getType(), "bvec3", &node->getSequence()); - outputTriplet(visit, "bvec3(", ", ", ")"); - break; - case EOpConstructBVec4: - addConstructor(node->getType(), "bvec4", &node->getSequence()); - outputTriplet(visit, "bvec4(", ", ", ")"); - break; - case EOpConstructInt: - addConstructor(node->getType(), "ivec1", &node->getSequence()); - outputTriplet(visit, "ivec1(", "", ")"); - break; - case EOpConstructIVec2: - addConstructor(node->getType(), "ivec2", &node->getSequence()); - outputTriplet(visit, "ivec2(", ", ", ")"); - break; - case EOpConstructIVec3: - addConstructor(node->getType(), "ivec3", &node->getSequence()); - outputTriplet(visit, "ivec3(", ", ", ")"); - break; - case EOpConstructIVec4: - addConstructor(node->getType(), "ivec4", &node->getSequence()); - outputTriplet(visit, "ivec4(", ", ", ")"); - break; - case EOpConstructMat2: - addConstructor(node->getType(), "mat2", &node->getSequence()); - outputTriplet(visit, "mat2(", ", ", ")"); - break; - case EOpConstructMat3: - addConstructor(node->getType(), "mat3", &node->getSequence()); - outputTriplet(visit, "mat3(", ", ", ")"); - break; - case EOpConstructMat4: - addConstructor(node->getType(), "mat4", &node->getSequence()); - outputTriplet(visit, "mat4(", ", ", ")"); - break; - case EOpConstructStruct: - addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence()); - outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")"); - break; - case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; - case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; - case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break; - case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break; - case EOpVectorEqual: outputTriplet(visit, "(", " == ", ")"); break; - case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break; - case EOpMod: - { - // We need to look at the number of components in both arguments - switch (node->getSequence()[0]->getAsTyped()->getNominalSize() * 10 - + node->getSequence()[1]->getAsTyped()->getNominalSize()) - { - case 11: mUsesMod1 = true; break; - case 22: mUsesMod2v = true; break; - case 21: mUsesMod2f = true; break; - case 33: mUsesMod3v = true; break; - case 31: mUsesMod3f = true; break; - case 44: mUsesMod4v = true; break; - case 41: mUsesMod4f = true; break; - default: UNREACHABLE(); - } - - outputTriplet(visit, "mod(", ", ", ")"); - } - break; - case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break; - case EOpAtan: - ASSERT(node->getSequence().size() == 2); // atan(x) is a unary operator - switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) - { - case 1: mUsesAtan2_1 = true; break; - case 2: mUsesAtan2_2 = true; break; - case 3: mUsesAtan2_3 = true; break; - case 4: mUsesAtan2_4 = true; break; - default: UNREACHABLE(); - } - outputTriplet(visit, "atanyx(", ", ", ")"); - break; - case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break; - case EOpMax: outputTriplet(visit, "max(", ", ", ")"); break; - case EOpClamp: outputTriplet(visit, "clamp(", ", ", ")"); break; - case EOpMix: outputTriplet(visit, "lerp(", ", ", ")"); break; - case EOpStep: outputTriplet(visit, "step(", ", ", ")"); break; - case EOpSmoothStep: outputTriplet(visit, "smoothstep(", ", ", ")"); break; - case EOpDistance: outputTriplet(visit, "distance(", ", ", ")"); break; - case EOpDot: outputTriplet(visit, "dot(", ", ", ")"); break; - case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break; - case EOpFaceForward: - { - switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument - { - case 1: mUsesFaceforward1 = true; break; - case 2: mUsesFaceforward2 = true; break; - case 3: mUsesFaceforward3 = true; break; - case 4: mUsesFaceforward4 = true; break; - default: UNREACHABLE(); - } - - outputTriplet(visit, "faceforward(", ", ", ")"); - } - break; - case EOpReflect: outputTriplet(visit, "reflect(", ", ", ")"); break; - case EOpRefract: outputTriplet(visit, "refract(", ", ", ")"); break; - case EOpMul: outputTriplet(visit, "(", " * ", ")"); break; - default: UNREACHABLE(); - } - - return true; -} - -bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) -{ - TInfoSinkBase &out = mBody; - - if (node->usesTernaryOperator()) - { - out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); - } - else // if/else statement - { - mUnfoldShortCircuit->traverse(node->getCondition()); - - out << "if ("; - - node->getCondition()->traverse(this); - - out << ")\n"; - - outputLineDirective(node->getLine().first_line); - out << "{\n"; - - bool discard = false; - - if (node->getTrueBlock()) - { - traverseStatements(node->getTrueBlock()); - - // Detect true discard - discard = (discard || FindDiscard::search(node->getTrueBlock())); - } - - outputLineDirective(node->getLine().first_line); - out << ";\n}\n"; - - if (node->getFalseBlock()) - { - out << "else\n"; - - outputLineDirective(node->getFalseBlock()->getLine().first_line); - out << "{\n"; - - outputLineDirective(node->getFalseBlock()->getLine().first_line); - traverseStatements(node->getFalseBlock()); - - outputLineDirective(node->getFalseBlock()->getLine().first_line); - out << ";\n}\n"; - - // Detect false discard - discard = (discard || FindDiscard::search(node->getFalseBlock())); - } - - // ANGLE issue 486: Detect problematic conditional discard - if (discard && FindSideEffectRewriting::search(node)) - { - mUsesDiscardRewriting = true; - } - } - - return false; -} - -void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node) -{ - writeConstantUnion(node->getType(), node->getUnionArrayPointer()); -} - -bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) -{ - bool wasDiscontinuous = mInsideDiscontinuousLoop; - - if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop) - { - mInsideDiscontinuousLoop = containsLoopDiscontinuity(node); - } - - if (mOutputType == SH_HLSL9_OUTPUT) - { - if (handleExcessiveLoop(node)) - { - return false; - } - } - - TInfoSinkBase &out = mBody; - - if (node->getType() == ELoopDoWhile) - { - out << "{do\n"; - - outputLineDirective(node->getLine().first_line); - out << "{\n"; - } - else - { - out << "{for("; - - if (node->getInit()) - { - node->getInit()->traverse(this); - } - - out << "; "; - - if (node->getCondition()) - { - node->getCondition()->traverse(this); - } - - out << "; "; - - if (node->getExpression()) - { - node->getExpression()->traverse(this); - } - - out << ")\n"; - - outputLineDirective(node->getLine().first_line); - out << "{\n"; - } - - if (node->getBody()) - { - traverseStatements(node->getBody()); - } - - outputLineDirective(node->getLine().first_line); - out << ";}\n"; - - if (node->getType() == ELoopDoWhile) - { - outputLineDirective(node->getCondition()->getLine().first_line); - out << "while(\n"; - - node->getCondition()->traverse(this); - - out << ");"; - } - - out << "}\n"; - - mInsideDiscontinuousLoop = wasDiscontinuous; - - return false; -} - -bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) -{ - TInfoSinkBase &out = mBody; - - switch (node->getFlowOp()) - { - case EOpKill: - outputTriplet(visit, "discard;\n", "", ""); - break; - case EOpBreak: - if (visit == PreVisit) - { - if (mExcessiveLoopIndex) - { - out << "{Break"; - mExcessiveLoopIndex->traverse(this); - out << " = true; break;}\n"; - } - else - { - out << "break;\n"; - } - } - break; - case EOpContinue: outputTriplet(visit, "continue;\n", "", ""); break; - case EOpReturn: - if (visit == PreVisit) - { - if (node->getExpression()) - { - out << "return "; - } - else - { - out << "return;\n"; - } - } - else if (visit == PostVisit) - { - if (node->getExpression()) - { - out << ";\n"; - } - } - break; - default: UNREACHABLE(); - } - - return true; -} - -void OutputHLSL::traverseStatements(TIntermNode *node) -{ - if (isSingleStatement(node)) - { - mUnfoldShortCircuit->traverse(node); - } - - node->traverse(this); -} - -bool OutputHLSL::isSingleStatement(TIntermNode *node) -{ - TIntermAggregate *aggregate = node->getAsAggregate(); - - if (aggregate) - { - if (aggregate->getOp() == EOpSequence) - { - return false; - } - else - { - for (TIntermSequence::iterator sit = aggregate->getSequence().begin(); sit != aggregate->getSequence().end(); sit++) - { - if (!isSingleStatement(*sit)) - { - return false; - } - } - - return true; - } - } - - return true; -} - -// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them -// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254). -bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) -{ - const int MAX_LOOP_ITERATIONS = 254; - TInfoSinkBase &out = mBody; - - // Parse loops of the form: - // for(int index = initial; index [comparator] limit; index += increment) - TIntermSymbol *index = NULL; - TOperator comparator = EOpNull; - int initial = 0; - int limit = 0; - int increment = 0; - - // Parse index name and intial value - if (node->getInit()) - { - TIntermAggregate *init = node->getInit()->getAsAggregate(); - - if (init) - { - TIntermSequence &sequence = init->getSequence(); - TIntermTyped *variable = sequence[0]->getAsTyped(); - - if (variable && variable->getQualifier() == EvqTemporary) - { - TIntermBinary *assign = variable->getAsBinaryNode(); - - if (assign->getOp() == EOpInitialize) - { - TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode(); - TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion(); - - if (symbol && constant) - { - if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1) - { - index = symbol; - initial = constant->getIConst(0); - } - } - } - } - } - } - - // Parse comparator and limit value - if (index != NULL && node->getCondition()) - { - TIntermBinary *test = node->getCondition()->getAsBinaryNode(); - - if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId()) - { - TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion(); - - if (constant) - { - if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1) - { - comparator = test->getOp(); - limit = constant->getIConst(0); - } - } - } - } - - // Parse increment - if (index != NULL && comparator != EOpNull && node->getExpression()) - { - TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode(); - TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode(); - - if (binaryTerminal) - { - TOperator op = binaryTerminal->getOp(); - TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion(); - - if (constant) - { - if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1) - { - int value = constant->getIConst(0); - - switch (op) - { - case EOpAddAssign: increment = value; break; - case EOpSubAssign: increment = -value; break; - default: UNIMPLEMENTED(); - } - } - } - } - else if (unaryTerminal) - { - TOperator op = unaryTerminal->getOp(); - - switch (op) - { - case EOpPostIncrement: increment = 1; break; - case EOpPostDecrement: increment = -1; break; - case EOpPreIncrement: increment = 1; break; - case EOpPreDecrement: increment = -1; break; - default: UNIMPLEMENTED(); - } - } - } - - if (index != NULL && comparator != EOpNull && increment != 0) - { - if (comparator == EOpLessThanEqual) - { - comparator = EOpLessThan; - limit += 1; - } - - if (comparator == EOpLessThan) - { - int iterations = (limit - initial) / increment; - - if (iterations <= MAX_LOOP_ITERATIONS) - { - return false; // Not an excessive loop - } - - TIntermSymbol *restoreIndex = mExcessiveLoopIndex; - mExcessiveLoopIndex = index; - - out << "{int "; - index->traverse(this); - out << ";\n" - "bool Break"; - index->traverse(this); - out << " = false;\n"; - - bool firstLoopFragment = true; - - while (iterations > 0) - { - int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations); - - if (!firstLoopFragment) - { - out << "if (!Break"; - index->traverse(this); - out << ") {\n"; - } - - if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment - { - mExcessiveLoopIndex = NULL; // Stops setting the Break flag - } - - // for(int index = initial; index < clampedLimit; index += increment) - - out << "for("; - index->traverse(this); - out << " = "; - out << initial; - - out << "; "; - index->traverse(this); - out << " < "; - out << clampedLimit; - - out << "; "; - index->traverse(this); - out << " += "; - out << increment; - out << ")\n"; - - outputLineDirective(node->getLine().first_line); - out << "{\n"; - - if (node->getBody()) - { - node->getBody()->traverse(this); - } - - outputLineDirective(node->getLine().first_line); - out << ";}\n"; - - if (!firstLoopFragment) - { - out << "}\n"; - } - - firstLoopFragment = false; - - initial += MAX_LOOP_ITERATIONS * increment; - iterations -= MAX_LOOP_ITERATIONS; - } - - out << "}"; - - mExcessiveLoopIndex = restoreIndex; - - return true; - } - else UNIMPLEMENTED(); - } - - return false; // Not handled as an excessive loop -} - -void OutputHLSL::outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString) -{ - TInfoSinkBase &out = mBody; - - if (visit == PreVisit) - { - out << preString; - } - else if (visit == InVisit) - { - out << inString; - } - else if (visit == PostVisit) - { - out << postString; - } -} - -void OutputHLSL::outputLineDirective(int line) -{ - if ((mContext.compileOptions & SH_LINE_DIRECTIVES) && (line > 0)) - { - mBody << "\n"; - mBody << "#line " << line; - - if (mContext.sourcePath) - { - mBody << " \"" << mContext.sourcePath << "\""; - } - - mBody << "\n"; - } -} - -TString OutputHLSL::argumentString(const TIntermSymbol *symbol) -{ - TQualifier qualifier = symbol->getQualifier(); - const TType &type = symbol->getType(); - TString name = symbol->getSymbol(); - - if (name.empty()) // HLSL demands named arguments, also for prototypes - { - name = "x" + str(mUniqueIndex++); - } - else - { - name = decorate(name); - } - - if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) - { - return qualifierString(qualifier) + " " + textureString(type) + " texture_" + name + arrayString(type) + ", " + - qualifierString(qualifier) + " SamplerState sampler_" + name + arrayString(type); - } - - return qualifierString(qualifier) + " " + typeString(type) + " " + name + arrayString(type); -} - -TString OutputHLSL::qualifierString(TQualifier qualifier) -{ - switch(qualifier) - { - case EvqIn: return "in"; - case EvqOut: return "out"; - case EvqInOut: return "inout"; - case EvqConstReadOnly: return "const"; - default: UNREACHABLE(); - } - - return ""; -} - -TString OutputHLSL::typeString(const TType &type) -{ - if (type.getBasicType() == EbtStruct) - { - const TString& typeName = type.getStruct()->name(); - if (typeName != "") - { - return structLookup(typeName); - } - else // Nameless structure, define in place - { - const TFieldList &fields = type.getStruct()->fields(); - - TString string = "struct\n" - "{\n"; - - for (unsigned int i = 0; i < fields.size(); i++) - { - const TField *field = fields[i]; - - string += " " + typeString(*field->type()) + " " + decorate(field->name()) + arrayString(*field->type()) + ";\n"; - } - - string += "} "; - - return string; - } - } - else if (type.isMatrix()) - { - switch (type.getNominalSize()) - { - case 2: return "float2x2"; - case 3: return "float3x3"; - case 4: return "float4x4"; - } - } - else - { - switch (type.getBasicType()) - { - case EbtFloat: - switch (type.getNominalSize()) - { - case 1: return "float"; - case 2: return "float2"; - case 3: return "float3"; - case 4: return "float4"; - } - case EbtInt: - switch (type.getNominalSize()) - { - case 1: return "int"; - case 2: return "int2"; - case 3: return "int3"; - case 4: return "int4"; - } - case EbtBool: - switch (type.getNominalSize()) - { - case 1: return "bool"; - case 2: return "bool2"; - case 3: return "bool3"; - case 4: return "bool4"; - } - case EbtVoid: - return "void"; - case EbtSampler2D: - return "sampler2D"; - case EbtSamplerCube: - return "samplerCUBE"; - case EbtSamplerExternalOES: - return "sampler2D"; - default: - break; - } - } - - UNREACHABLE(); - return "<unknown type>"; -} - -TString OutputHLSL::textureString(const TType &type) -{ - switch (type.getBasicType()) - { - case EbtSampler2D: - return "Texture2D"; - case EbtSamplerCube: - return "TextureCube"; - case EbtSamplerExternalOES: - return "Texture2D"; - default: - break; - } - - UNREACHABLE(); - return "<unknown texture type>"; -} - -TString OutputHLSL::arrayString(const TType &type) -{ - if (!type.isArray()) - { - return ""; - } - - return "[" + str(type.getArraySize()) + "]"; -} - -TString OutputHLSL::initializer(const TType &type) -{ - TString string; - - size_t size = type.getObjectSize(); - for (size_t component = 0; component < size; component++) - { - string += "0"; - - if (component + 1 < size) - { - string += ", "; - } - } - - return "{" + string + "}"; -} - -void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) -{ - if (name == "") - { - return; // Nameless structures don't have constructors - } - - if (type.getStruct() && mStructNames.find(decorate(name)) != mStructNames.end()) - { - return; // Already added - } - - TType ctorType = type; - ctorType.clearArrayness(); - ctorType.setPrecision(EbpHigh); - ctorType.setQualifier(EvqTemporary); - - TString ctorName = type.getStruct() ? decorate(name) : name; - - typedef std::vector<TType> ParameterArray; - ParameterArray ctorParameters; - - if (type.getStruct()) - { - mStructNames.insert(decorate(name)); - - TString structure; - structure += "struct " + decorate(name) + "\n" - "{\n"; - - const TFieldList &fields = type.getStruct()->fields(); - - for (unsigned int i = 0; i < fields.size(); i++) - { - const TField *field = fields[i]; - - structure += " " + typeString(*field->type()) + " " + decorateField(field->name(), type) + arrayString(*field->type()) + ";\n"; - } - - structure += "};\n"; - - if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end()) - { - mStructDeclarations.push_back(structure); - } - - for (unsigned int i = 0; i < fields.size(); i++) - { - ctorParameters.push_back(*fields[i]->type()); - } - } - else if (parameters) - { - for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) - { - ctorParameters.push_back((*parameter)->getAsTyped()->getType()); - } - } - else UNREACHABLE(); - - TString constructor; - - if (ctorType.getStruct()) - { - constructor += ctorName + " " + ctorName + "_ctor("; - } - else // Built-in type - { - constructor += typeString(ctorType) + " " + ctorName + "("; - } - - for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++) - { - const TType &type = ctorParameters[parameter]; - - constructor += typeString(type) + " x" + str(parameter) + arrayString(type); - - if (parameter < ctorParameters.size() - 1) - { - constructor += ", "; - } - } - - constructor += ")\n" - "{\n"; - - if (ctorType.getStruct()) - { - constructor += " " + ctorName + " structure = {"; - } - else - { - constructor += " return " + typeString(ctorType) + "("; - } - - if (ctorType.isMatrix() && ctorParameters.size() == 1) - { - int dim = ctorType.getNominalSize(); - const TType ¶meter = ctorParameters[0]; - - if (parameter.isScalar()) - { - for (int row = 0; row < dim; row++) - { - for (int col = 0; col < dim; col++) - { - constructor += TString((row == col) ? "x0" : "0.0"); - - if (row < dim - 1 || col < dim - 1) - { - constructor += ", "; - } - } - } - } - else if (parameter.isMatrix()) - { - for (int row = 0; row < dim; row++) - { - for (int col = 0; col < dim; col++) - { - if (row < parameter.getNominalSize() && col < parameter.getNominalSize()) - { - constructor += TString("x0") + "[" + str(row) + "]" + "[" + str(col) + "]"; - } - else - { - constructor += TString((row == col) ? "1.0" : "0.0"); - } - - if (row < dim - 1 || col < dim - 1) - { - constructor += ", "; - } - } - } - } - else UNREACHABLE(); - } - else - { - size_t remainingComponents = ctorType.getObjectSize(); - size_t parameterIndex = 0; - - while (remainingComponents > 0) - { - const TType ¶meter = ctorParameters[parameterIndex]; - const size_t parameterSize = parameter.getObjectSize(); - bool moreParameters = parameterIndex + 1 < ctorParameters.size(); - - constructor += "x" + str(parameterIndex); - - if (parameter.isScalar()) - { - ASSERT(parameterSize <= remainingComponents); - remainingComponents -= parameterSize; - } - else if (parameter.isVector()) - { - if (remainingComponents == parameterSize || moreParameters) - { - ASSERT(parameterSize <= remainingComponents); - remainingComponents -= parameterSize; - } - else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize())) - { - switch (remainingComponents) - { - case 1: constructor += ".x"; break; - case 2: constructor += ".xy"; break; - case 3: constructor += ".xyz"; break; - case 4: constructor += ".xyzw"; break; - default: UNREACHABLE(); - } - - remainingComponents = 0; - } - else UNREACHABLE(); - } - else if (parameter.isMatrix() || parameter.getStruct()) - { - ASSERT(remainingComponents == parameterSize || moreParameters); - ASSERT(parameterSize <= remainingComponents); - - remainingComponents -= parameterSize; - } - else UNREACHABLE(); - - if (moreParameters) - { - parameterIndex++; - } - - if (remainingComponents) - { - constructor += ", "; - } - } - } - - if (ctorType.getStruct()) - { - constructor += "};\n" - " return structure;\n" - "}\n"; - } - else - { - constructor += ");\n" - "}\n"; - } - - mConstructors.insert(constructor); -} - -const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const ConstantUnion *constUnion) -{ - TInfoSinkBase &out = mBody; - - if (type.getBasicType() == EbtStruct) - { - out << structLookup(type.getStruct()->name()) + "_ctor("; - - const TFieldList &fields = type.getStruct()->fields(); - - for (size_t i = 0; i < fields.size(); i++) - { - const TType *fieldType = fields[i]->type(); - - constUnion = writeConstantUnion(*fieldType, constUnion); - - if (i != fields.size() - 1) - { - out << ", "; - } - } - - out << ")"; - } - else - { - size_t size = type.getObjectSize(); - bool writeType = size > 1; - - if (writeType) - { - out << typeString(type) << "("; - } - - for (size_t i = 0; i < size; i++, constUnion++) - { - switch (constUnion->getType()) - { - case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); break; - case EbtInt: out << constUnion->getIConst(); break; - case EbtBool: out << constUnion->getBConst(); break; - default: UNREACHABLE(); - } - - if (i != size - 1) - { - out << ", "; - } - } - - if (writeType) - { - out << ")"; - } - } - - return constUnion; -} - -TString OutputHLSL::scopeString(unsigned int depthLimit) -{ - TString string; - - for (unsigned int i = 0; i < mScopeBracket.size() && i < depthLimit; i++) - { - string += "_" + str(i); - } - - return string; -} - -TString OutputHLSL::scopedStruct(const TString &typeName) -{ - if (typeName == "") - { - return typeName; - } - - return typeName + scopeString(mScopeDepth); -} - -TString OutputHLSL::structLookup(const TString &typeName) -{ - for (int depth = mScopeDepth; depth >= 0; depth--) - { - TString scopedName = decorate(typeName + scopeString(depth)); - - for (StructNames::iterator structName = mStructNames.begin(); structName != mStructNames.end(); structName++) - { - if (*structName == scopedName) - { - return scopedName; - } - } - } - - UNREACHABLE(); // Should have found a matching constructor - - return typeName; -} - -TString OutputHLSL::decorate(const TString &string) -{ - if (string.compare(0, 3, "gl_") != 0 && string.compare(0, 3, "dx_") != 0) - { - return "_" + string; - } - - return string; -} - -TString OutputHLSL::decorateUniform(const TString &string, const TType &type) -{ - if (type.getBasicType() == EbtSamplerExternalOES) - { - return "ex_" + string; - } - - return decorate(string); -} - -TString OutputHLSL::decorateField(const TString &string, const TType &structure) -{ - if (structure.getStruct()->name().compare(0, 3, "gl_") != 0) - { - return decorate(string); - } - - return string; -} - -TString OutputHLSL::registerString(TIntermSymbol *operand) -{ - ASSERT(operand->getQualifier() == EvqUniform); - - if (IsSampler(operand->getBasicType())) - { - return "s" + str(samplerRegister(operand)); - } - - return "c" + str(uniformRegister(operand)); -} - -int OutputHLSL::samplerRegister(TIntermSymbol *sampler) -{ - const TType &type = sampler->getType(); - ASSERT(IsSampler(type.getBasicType())); - - int index = mSamplerRegister; - mSamplerRegister += sampler->totalRegisterCount(); - - declareUniform(type, sampler->getSymbol(), index); - - return index; -} - -int OutputHLSL::uniformRegister(TIntermSymbol *uniform) -{ - const TType &type = uniform->getType(); - ASSERT(!IsSampler(type.getBasicType())); - - int index = mUniformRegister; - mUniformRegister += uniform->totalRegisterCount(); - - declareUniform(type, uniform->getSymbol(), index); - - return index; -} - -void OutputHLSL::declareUniform(const TType &type, const TString &name, int index) -{ - TStructure *structure = type.getStruct(); - - if (!structure) - { - mActiveUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index)); - } - else - { - const TFieldList &fields = structure->fields(); - - if (type.isArray()) - { - int elementIndex = index; - - for (int i = 0; i < type.getArraySize(); i++) - { - for (size_t j = 0; j < fields.size(); j++) - { - const TType &fieldType = *fields[j]->type(); - const TString uniformName = name + "[" + str(i) + "]." + fields[j]->name(); - declareUniform(fieldType, uniformName, elementIndex); - elementIndex += fieldType.totalRegisterCount(); - } - } - } - else - { - int fieldIndex = index; - - for (size_t i = 0; i < fields.size(); i++) - { - const TType &fieldType = *fields[i]->type(); - const TString uniformName = name + "." + fields[i]->name(); - declareUniform(fieldType, uniformName, fieldIndex); - fieldIndex += fieldType.totalRegisterCount(); - } - } - } -} - -GLenum OutputHLSL::glVariableType(const TType &type) -{ - if (type.getBasicType() == EbtFloat) - { - if (type.isScalar()) - { - return GL_FLOAT; - } - else if (type.isVector()) - { - switch(type.getNominalSize()) - { - case 2: return GL_FLOAT_VEC2; - case 3: return GL_FLOAT_VEC3; - case 4: return GL_FLOAT_VEC4; - default: UNREACHABLE(); - } - } - else if (type.isMatrix()) - { - switch(type.getNominalSize()) - { - case 2: return GL_FLOAT_MAT2; - case 3: return GL_FLOAT_MAT3; - case 4: return GL_FLOAT_MAT4; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - } - else if (type.getBasicType() == EbtInt) - { - if (type.isScalar()) - { - return GL_INT; - } - else if (type.isVector()) - { - switch(type.getNominalSize()) - { - case 2: return GL_INT_VEC2; - case 3: return GL_INT_VEC3; - case 4: return GL_INT_VEC4; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - } - else if (type.getBasicType() == EbtBool) - { - if (type.isScalar()) - { - return GL_BOOL; - } - else if (type.isVector()) - { - switch(type.getNominalSize()) - { - case 2: return GL_BOOL_VEC2; - case 3: return GL_BOOL_VEC3; - case 4: return GL_BOOL_VEC4; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - } - else if (type.getBasicType() == EbtSampler2D) - { - return GL_SAMPLER_2D; - } - else if (type.getBasicType() == EbtSamplerCube) - { - return GL_SAMPLER_CUBE; - } - else UNREACHABLE(); - - return GL_NONE; -} - -GLenum OutputHLSL::glVariablePrecision(const TType &type) -{ - if (type.getBasicType() == EbtFloat) - { - switch (type.getPrecision()) - { - case EbpHigh: return GL_HIGH_FLOAT; - case EbpMedium: return GL_MEDIUM_FLOAT; - case EbpLow: return GL_LOW_FLOAT; - case EbpUndefined: - // Should be defined as the default precision by the parser - default: UNREACHABLE(); - } - } - else if (type.getBasicType() == EbtInt) - { - switch (type.getPrecision()) - { - case EbpHigh: return GL_HIGH_INT; - case EbpMedium: return GL_MEDIUM_INT; - case EbpLow: return GL_LOW_INT; - case EbpUndefined: - // Should be defined as the default precision by the parser - default: UNREACHABLE(); - } - } - - // Other types (boolean, sampler) don't have a precision - return GL_NONE; -} - -} diff --git a/chromium/third_party/angle/src/compiler/RemoveTree.cpp b/chromium/third_party/angle/src/compiler/RemoveTree.cpp deleted file mode 100644 index a4b8c1e63e1..00000000000 --- a/chromium/third_party/angle/src/compiler/RemoveTree.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/intermediate.h" -#include "compiler/RemoveTree.h" - -// -// Code to recursively delete the intermediate tree. -// - -class RemoveTree : public TIntermTraverser -{ -public: - RemoveTree() : TIntermTraverser(false, false, true) - { - } - -protected: - void visitSymbol(TIntermSymbol*); - void visitConstantUnion(TIntermConstantUnion*); - bool visitBinary(Visit visit, TIntermBinary*); - bool visitUnary(Visit visit, TIntermUnary*); - bool visitSelection(Visit visit, TIntermSelection*); - bool visitAggregate(Visit visit, TIntermAggregate*); -}; - -void RemoveTree::visitSymbol(TIntermSymbol* node) -{ - delete node; -} - -bool RemoveTree::visitBinary(Visit visit, TIntermBinary* node) -{ - delete node; - - return true; -} - -bool RemoveTree::visitUnary(Visit visit, TIntermUnary* node) -{ - delete node; - - return true; -} - -bool RemoveTree::visitAggregate(Visit visit, TIntermAggregate* node) -{ - delete node; - - return true; -} - -bool RemoveTree::visitSelection(Visit visit, TIntermSelection* node) -{ - delete node; - - return true; -} - -void RemoveTree::visitConstantUnion(TIntermConstantUnion* node) -{ - delete node; -} - -// -// Entry point. -// -void RemoveAllTreeNodes(TIntermNode* root) -{ - RemoveTree it; - - root->traverse(&it); -} - diff --git a/chromium/third_party/angle/src/compiler/SymbolTable.cpp b/chromium/third_party/angle/src/compiler/SymbolTable.cpp deleted file mode 100644 index a7ce21680f5..00000000000 --- a/chromium/third_party/angle/src/compiler/SymbolTable.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// -// Symbol table for parsing. Most functionaliy and main ideas -// are documented in the header file. -// - -#if defined(_MSC_VER) -#pragma warning(disable: 4718) -#endif - -#include "compiler/SymbolTable.h" - -#include <stdio.h> -#include <algorithm> -#include <climits> - -TType::TType(const TPublicType &p) : - type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0) -{ - if (p.userDef) - structure = p.userDef->getStruct(); -} - -// -// Recursively generate mangled names. -// -TString TType::buildMangledName() const -{ - TString mangledName; - if (isMatrix()) - mangledName += 'm'; - else if (isVector()) - mangledName += 'v'; - - switch (type) { - case EbtFloat: mangledName += 'f'; break; - case EbtInt: mangledName += 'i'; break; - case EbtBool: mangledName += 'b'; break; - case EbtSampler2D: mangledName += "s2"; break; - case EbtSamplerCube: mangledName += "sC"; break; - case EbtStruct: mangledName += structure->mangledName(); break; - default: break; - } - - mangledName += static_cast<char>('0' + getNominalSize()); - if (isArray()) { - char buf[20]; - snprintf(buf, sizeof(buf), "%d", arraySize); - mangledName += '['; - mangledName += buf; - mangledName += ']'; - } - return mangledName; -} - -size_t TType::getObjectSize() const -{ - size_t totalSize = 0; - - if (getBasicType() == EbtStruct) - totalSize = structure->objectSize(); - else if (matrix) - totalSize = size * size; - else - totalSize = size; - - if (isArray()) { - size_t arraySize = getArraySize(); - if (arraySize > INT_MAX / totalSize) - totalSize = INT_MAX; - else - totalSize *= arraySize; - } - - return totalSize; -} - -bool TStructure::containsArrays() const -{ - for (size_t i = 0; i < mFields->size(); ++i) { - const TType* fieldType = (*mFields)[i]->type(); - if (fieldType->isArray() || fieldType->isStructureContainingArrays()) - return true; - } - return false; -} - -TString TStructure::buildMangledName() const -{ - TString mangledName("struct-"); - mangledName += *mName; - for (size_t i = 0; i < mFields->size(); ++i) { - mangledName += '-'; - mangledName += (*mFields)[i]->type()->getMangledName(); - } - return mangledName; -} - -size_t TStructure::calculateObjectSize() const -{ - size_t size = 0; - for (size_t i = 0; i < mFields->size(); ++i) { - size_t fieldSize = (*mFields)[i]->type()->getObjectSize(); - if (fieldSize > INT_MAX - size) - size = INT_MAX; - else - size += fieldSize; - } - return size; -} - -int TStructure::calculateDeepestNesting() const -{ - int maxNesting = 0; - for (size_t i = 0; i < mFields->size(); ++i) { - maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting()); - } - return 1 + maxNesting; -} - -// -// Dump functions. -// - -void TVariable::dump(TInfoSink& infoSink) const -{ - infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString(); - if (type.isArray()) { - infoSink.debug << "[0]"; - } - infoSink.debug << "\n"; -} - -void TFunction::dump(TInfoSink &infoSink) const -{ - infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n"; -} - -void TSymbolTableLevel::dump(TInfoSink &infoSink) const -{ - tLevel::const_iterator it; - for (it = level.begin(); it != level.end(); ++it) - (*it).second->dump(infoSink); -} - -void TSymbolTable::dump(TInfoSink &infoSink) const -{ - for (int level = currentLevel(); level >= 0; --level) { - infoSink.debug << "LEVEL " << level << "\n"; - table[level]->dump(infoSink); - } -} - -// -// Functions have buried pointers to delete. -// -TFunction::~TFunction() -{ - for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) - delete (*i).type; -} - -// -// Symbol table levels are a map of pointers to symbols that have to be deleted. -// -TSymbolTableLevel::~TSymbolTableLevel() -{ - for (tLevel::iterator it = level.begin(); it != level.end(); ++it) - delete (*it).second; -} - -// -// Change all function entries in the table with the non-mangled name -// to be related to the provided built-in operation. This is a low -// performance operation, and only intended for symbol tables that -// live across a large number of compiles. -// -void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) -{ - tLevel::iterator it; - for (it = level.begin(); it != level.end(); ++it) { - if ((*it).second->isFunction()) { - TFunction* function = static_cast<TFunction*>((*it).second); - if (function->getName() == name) - function->relateToOperator(op); - } - } -} - -// -// Change all function entries in the table with the non-mangled name -// to be related to the provided built-in extension. This is a low -// performance operation, and only intended for symbol tables that -// live across a large number of compiles. -// -void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) -{ - for (tLevel::iterator it = level.begin(); it != level.end(); ++it) { - TSymbol* symbol = it->second; - if (symbol->getName() == name) - symbol->relateToExtension(ext); - } -} - -TSymbolTable::~TSymbolTable() -{ - for (size_t i = 0; i < table.size(); ++i) - delete table[i]; - for (size_t i = 0; i < precisionStack.size(); ++i) - delete precisionStack[i]; -} diff --git a/chromium/third_party/angle/src/compiler/SymbolTable.h b/chromium/third_party/angle/src/compiler/SymbolTable.h deleted file mode 100644 index bebad4b92e7..00000000000 --- a/chromium/third_party/angle/src/compiler/SymbolTable.h +++ /dev/null @@ -1,382 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef _SYMBOL_TABLE_INCLUDED_ -#define _SYMBOL_TABLE_INCLUDED_ - -// -// Symbol table for parsing. Has these design characteristics: -// -// * Same symbol table can be used to compile many shaders, to preserve -// effort of creating and loading with the large numbers of built-in -// symbols. -// -// * Name mangling will be used to give each function a unique name -// so that symbol table lookups are never ambiguous. This allows -// a simpler symbol table structure. -// -// * Pushing and popping of scope, so symbol table will really be a stack -// of symbol tables. Searched from the top, with new inserts going into -// the top. -// -// * Constants: Compile time constant symbols will keep their values -// in the symbol table. The parser can substitute constants at parse -// time, including doing constant folding and constant propagation. -// -// * No temporaries: Temporaries made from operations (+, --, .xy, etc.) -// are tracked in the intermediate representation, not the symbol table. -// - -#include <assert.h> - -#include "common/angleutils.h" -#include "compiler/InfoSink.h" -#include "compiler/intermediate.h" - -// -// Symbol base class. (Can build functions or variables out of these...) -// -class TSymbol { -public: - POOL_ALLOCATOR_NEW_DELETE(); - TSymbol(const TString* n) : uniqueId(0), name(n) { } - virtual ~TSymbol() { /* don't delete name, it's from the pool */ } - - const TString& getName() const { return *name; } - virtual const TString& getMangledName() const { return getName(); } - virtual bool isFunction() const { return false; } - virtual bool isVariable() const { return false; } - void setUniqueId(int id) { uniqueId = id; } - int getUniqueId() const { return uniqueId; } - virtual void dump(TInfoSink &infoSink) const = 0; - void relateToExtension(const TString& ext) { extension = ext; } - const TString& getExtension() const { return extension; } - -private: - DISALLOW_COPY_AND_ASSIGN(TSymbol); - - int uniqueId; // For real comparing during code generation - const TString *name; - TString extension; -}; - -// -// Variable class, meaning a symbol that's not a function. -// -// There could be a separate class heirarchy for Constant variables; -// Only one of int, bool, or float, (or none) is correct for -// any particular use, but it's easy to do this way, and doesn't -// seem worth having separate classes, and "getConst" can't simply return -// different values for different types polymorphically, so this is -// just simple and pragmatic. -// -class TVariable : public TSymbol { -public: - TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0) { } - virtual ~TVariable() { } - virtual bool isVariable() const { return true; } - TType& getType() { return type; } - const TType& getType() const { return type; } - bool isUserType() const { return userType; } - void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); } - - virtual void dump(TInfoSink &infoSink) const; - - ConstantUnion* getConstPointer() - { - if (!unionArray) - unionArray = new ConstantUnion[type.getObjectSize()]; - - return unionArray; - } - - ConstantUnion* getConstPointer() const { return unionArray; } - - void shareConstPointer( ConstantUnion *constArray) - { - if (unionArray == constArray) - return; - - delete[] unionArray; - unionArray = constArray; - } - -private: - DISALLOW_COPY_AND_ASSIGN(TVariable); - - TType type; - bool userType; - // we are assuming that Pool Allocator will free the memory allocated to unionArray - // when this object is destroyed - ConstantUnion *unionArray; -}; - -// -// The function sub-class of symbols and the parser will need to -// share this definition of a function parameter. -// -struct TParameter { - TString *name; - TType* type; -}; - -// -// The function sub-class of a symbol. -// -class TFunction : public TSymbol { -public: - TFunction(TOperator o) : - TSymbol(0), - returnType(TType(EbtVoid, EbpUndefined)), - op(o), - defined(false) { } - TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) : - TSymbol(name), - returnType(retType), - mangledName(TFunction::mangleName(*name)), - op(tOp), - defined(false) { } - virtual ~TFunction(); - virtual bool isFunction() const { return true; } - - static TString mangleName(const TString& name) { return name + '('; } - static TString unmangleName(const TString& mangledName) - { - return TString(mangledName.c_str(), mangledName.find_first_of('(')); - } - - void addParameter(TParameter& p) - { - parameters.push_back(p); - mangledName = mangledName + p.type->getMangledName(); - } - - const TString& getMangledName() const { return mangledName; } - const TType& getReturnType() const { return returnType; } - - void relateToOperator(TOperator o) { op = o; } - TOperator getBuiltInOp() const { return op; } - - void setDefined() { defined = true; } - bool isDefined() { return defined; } - - size_t getParamCount() const { return parameters.size(); } - const TParameter& getParam(size_t i) const { return parameters[i]; } - - virtual void dump(TInfoSink &infoSink) const; - -private: - DISALLOW_COPY_AND_ASSIGN(TFunction); - - typedef TVector<TParameter> TParamList; - TParamList parameters; - TType returnType; - TString mangledName; - TOperator op; - bool defined; -}; - - -class TSymbolTableLevel { -public: - typedef TMap<TString, TSymbol*> tLevel; - typedef tLevel::const_iterator const_iterator; - typedef const tLevel::value_type tLevelPair; - typedef std::pair<tLevel::iterator, bool> tInsertResult; - - TSymbolTableLevel() { } - ~TSymbolTableLevel(); - - bool insert(const TString &name, TSymbol &symbol) - { - // - // returning true means symbol was added to the table - // - tInsertResult result = level.insert(tLevelPair(name, &symbol)); - - return result.second; - } - - bool insert(TSymbol &symbol) - { - return insert(symbol.getMangledName(), symbol); - } - - TSymbol* find(const TString& name) const - { - tLevel::const_iterator it = level.find(name); - if (it == level.end()) - return 0; - else - return (*it).second; - } - - const_iterator begin() const - { - return level.begin(); - } - - const_iterator end() const - { - return level.end(); - } - - void relateToOperator(const char* name, TOperator op); - void relateToExtension(const char* name, const TString& ext); - void dump(TInfoSink &infoSink) const; - -protected: - tLevel level; -}; - -class TSymbolTable { -public: - TSymbolTable() : uniqueId(0) - { - // - // The symbol table cannot be used until push() is called, but - // the lack of an initial call to push() can be used to detect - // that the symbol table has not been preloaded with built-ins. - // - } - ~TSymbolTable(); - - // - // When the symbol table is initialized with the built-ins, there should - // 'push' calls, so that built-ins are at level 0 and the shader - // globals are at level 1. - // - bool isEmpty() { return table.size() == 0; } - bool atBuiltInLevel() { return table.size() == 1; } - bool atGlobalLevel() { return table.size() <= 2; } - void push() - { - table.push_back(new TSymbolTableLevel); - precisionStack.push_back(new PrecisionStackLevel); - } - - void pop() - { - delete table.back(); - table.pop_back(); - - delete precisionStack.back(); - precisionStack.pop_back(); - } - - bool insert(TSymbol& symbol) - { - symbol.setUniqueId(++uniqueId); - return table[currentLevel()]->insert(symbol); - } - - bool insertConstInt(const char *name, int value) - { - TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); - constant->getConstPointer()->setIConst(value); - return insert(*constant); - } - - bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0) - { - TFunction *function = new TFunction(NewPoolTString(name), *rvalue); - - TParameter param1 = {NULL, ptype1}; - function->addParameter(param1); - - if(ptype2) - { - TParameter param2 = {NULL, ptype2}; - function->addParameter(param2); - } - - if(ptype3) - { - TParameter param3 = {NULL, ptype3}; - function->addParameter(param3); - } - - return insert(*function); - } - - TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0) - { - int level = currentLevel(); - TSymbol* symbol; - do { - symbol = table[level]->find(name); - --level; - } while (symbol == 0 && level >= 0); - level++; - if (builtIn) - *builtIn = level == 0; - if (sameScope) - *sameScope = level == currentLevel(); - return symbol; - } - - TSymbol* findBuiltIn(const TString &name) - { - return table[0]->find(name); - } - - TSymbolTableLevel* getOuterLevel() { - assert(table.size() >= 2); - return table[currentLevel() - 1]; - } - - void relateToOperator(const char* name, TOperator op) { - table[0]->relateToOperator(name, op); - } - void relateToExtension(const char* name, const TString& ext) { - table[0]->relateToExtension(name, ext); - } - void dump(TInfoSink &infoSink) const; - - bool setDefaultPrecision(const TPublicType& type, TPrecision prec) { - if (!supportsPrecision(type.type)) - return false; - if (type.size != 1 || type.matrix || type.array) - return false; // Not allowed to set for aggregate types - int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; - (*precisionStack[indexOfLastElement])[type.type] = prec; // Uses map operator [], overwrites the current value - return true; - } - - // Searches down the precisionStack for a precision qualifier for the specified TBasicType - TPrecision getDefaultPrecision(TBasicType type) { - if (!supportsPrecision(type)) - return EbpUndefined; - int level = static_cast<int>(precisionStack.size()) - 1; - assert(level >= 0); // Just to be safe. Should not happen. - PrecisionStackLevel::iterator it; - TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this? - while (level >= 0) { - it = precisionStack[level]->find(type); - if (it != precisionStack[level]->end()) { - prec = (*it).second; - break; - } - level--; - } - return prec; - } - -private: - int currentLevel() const { return static_cast<int>(table.size()) - 1; } - - bool supportsPrecision(TBasicType type) { - // Only supports precision for int, float, and sampler types. - return type == EbtFloat || type == EbtInt || IsSampler(type); - } - - int uniqueId; // for unique identification in code generation - std::vector<TSymbolTableLevel*> table; - typedef TMap<TBasicType, TPrecision> PrecisionStackLevel; - std::vector<PrecisionStackLevel*> precisionStack; -}; - -#endif // _SYMBOL_TABLE_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/TranslatorHLSL.cpp b/chromium/third_party/angle/src/compiler/TranslatorHLSL.cpp deleted file mode 100644 index 37408a07c49..00000000000 --- a/chromium/third_party/angle/src/compiler/TranslatorHLSL.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/TranslatorHLSL.h" - -#include "compiler/InitializeParseContext.h" -#include "compiler/OutputHLSL.h" - -TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output) - : TCompiler(type, spec), mOutputType(output) -{ -} - -void TranslatorHLSL::translate(TIntermNode *root) -{ - TParseContext& parseContext = *GetGlobalParseContext(); - sh::OutputHLSL outputHLSL(parseContext, getResources(), mOutputType); - - outputHLSL.output(); - mActiveUniforms = outputHLSL.getUniforms(); -} diff --git a/chromium/third_party/angle/src/compiler/TranslatorHLSL.h b/chromium/third_party/angle/src/compiler/TranslatorHLSL.h deleted file mode 100644 index 9550e15e8ef..00000000000 --- a/chromium/third_party/angle/src/compiler/TranslatorHLSL.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATORHLSL_H_ -#define COMPILER_TRANSLATORHLSL_H_ - -#include "compiler/ShHandle.h" -#include "compiler/Uniform.h" - -class TranslatorHLSL : public TCompiler { -public: - TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output); - - virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; } - const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; } - -protected: - virtual void translate(TIntermNode* root); - - sh::ActiveUniforms mActiveUniforms; - ShShaderOutput mOutputType; -}; - -#endif // COMPILER_TRANSLATORHLSL_H_ diff --git a/chromium/third_party/angle/src/compiler/Types.h b/chromium/third_party/angle/src/compiler/Types.h deleted file mode 100644 index 75560ddc6ef..00000000000 --- a/chromium/third_party/angle/src/compiler/Types.h +++ /dev/null @@ -1,307 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef _TYPES_INCLUDED -#define _TYPES_INCLUDED - -#include "common/angleutils.h" - -#include "compiler/BaseTypes.h" -#include "compiler/Common.h" -#include "compiler/debug.h" - -struct TPublicType; -class TType; - -class TField -{ -public: - POOL_ALLOCATOR_NEW_DELETE(); - TField(TType* type, TString* name) : mType(type), mName(name) {} - - // TODO(alokp): We should only return const type. - // Fix it by tweaking grammar. - TType* type() { return mType; } - const TType* type() const { return mType; } - - const TString& name() const { return *mName; } - -private: - DISALLOW_COPY_AND_ASSIGN(TField); - TType* mType; - TString* mName; -}; - -typedef TVector<TField*> TFieldList; -inline TFieldList* NewPoolTFieldList() -{ - void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList)); - return new(memory) TFieldList; -} - -class TStructure -{ -public: - POOL_ALLOCATOR_NEW_DELETE(); - TStructure(TString* name, TFieldList* fields) - : mName(name), - mFields(fields), - mObjectSize(0), - mDeepestNesting(0) { - } - - const TString& name() const { return *mName; } - const TFieldList& fields() const { return *mFields; } - - const TString& mangledName() const { - if (mMangledName.empty()) - mMangledName = buildMangledName(); - return mMangledName; - } - size_t objectSize() const { - if (mObjectSize == 0) - mObjectSize = calculateObjectSize(); - return mObjectSize; - }; - int deepestNesting() const { - if (mDeepestNesting == 0) - mDeepestNesting = calculateDeepestNesting(); - return mDeepestNesting; - } - bool containsArrays() const; - -private: - DISALLOW_COPY_AND_ASSIGN(TStructure); - TString buildMangledName() const; - size_t calculateObjectSize() const; - int calculateDeepestNesting() const; - - TString* mName; - TFieldList* mFields; - - mutable TString mMangledName; - mutable size_t mObjectSize; - mutable int mDeepestNesting; -}; - -// -// Base class for things that have a type. -// -class TType -{ -public: - POOL_ALLOCATOR_NEW_DELETE(); - TType() {} - TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char s = 1, bool m = false, bool a = false) : - type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0) - { - } - explicit TType(const TPublicType &p); - TType(TStructure* userDef, TPrecision p = EbpUndefined) : - type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef) - { - } - - TBasicType getBasicType() const { return type; } - void setBasicType(TBasicType t) { type = t; } - - TPrecision getPrecision() const { return precision; } - void setPrecision(TPrecision p) { precision = p; } - - TQualifier getQualifier() const { return qualifier; } - void setQualifier(TQualifier q) { qualifier = q; } - - // One-dimensional size of single instance type - int getNominalSize() const { return size; } - void setNominalSize(unsigned char s) { size = s; } - // Full size of single instance of type - size_t getObjectSize() const; - - int elementRegisterCount() const - { - if (structure) - { - const TFieldList &fields = getStruct()->fields(); - int registerCount = 0; - - for (size_t i = 0; i < fields.size(); i++) - { - registerCount += fields[i]->type()->totalRegisterCount(); - } - - return registerCount; - } - else if (isMatrix()) - { - return getNominalSize(); - } - else - { - return 1; - } - } - - int totalRegisterCount() const - { - if (array) - { - return arraySize * elementRegisterCount(); - } - else - { - return elementRegisterCount(); - } - } - - bool isMatrix() const { return matrix ? true : false; } - void setMatrix(bool m) { matrix = m; } - - bool isArray() const { return array ? true : false; } - int getArraySize() const { return arraySize; } - void setArraySize(int s) { array = true; arraySize = s; } - void clearArrayness() { array = false; arraySize = 0; } - - bool isVector() const { return size > 1 && !matrix; } - bool isScalar() const { return size == 1 && !matrix && !structure; } - - TStructure* getStruct() const { return structure; } - void setStruct(TStructure* s) { structure = s; } - - const TString& getMangledName() const { - if (mangled.empty()) { - mangled = buildMangledName(); - mangled += ';'; - } - return mangled; - } - - bool sameElementType(const TType& right) const { - return type == right.type && - size == right.size && - matrix == right.matrix && - structure == right.structure; - } - bool operator==(const TType& right) const { - return type == right.type && - size == right.size && - matrix == right.matrix && - array == right.array && (!array || arraySize == right.arraySize) && - structure == right.structure; - // don't check the qualifier, it's not ever what's being sought after - } - bool operator!=(const TType& right) const { - return !operator==(right); - } - bool operator<(const TType& right) const { - if (type != right.type) return type < right.type; - if (size != right.size) return size < right.size; - if (matrix != right.matrix) return matrix < right.matrix; - if (array != right.array) return array < right.array; - if (arraySize != right.arraySize) return arraySize < right.arraySize; - if (structure != right.structure) return structure < right.structure; - - return false; - } - - const char* getBasicString() const { return ::getBasicString(type); } - const char* getPrecisionString() const { return ::getPrecisionString(precision); } - const char* getQualifierString() const { return ::getQualifierString(qualifier); } - TString getCompleteString() const; - - // If this type is a struct, returns the deepest struct nesting of - // any field in the struct. For example: - // struct nesting1 { - // vec4 position; - // }; - // struct nesting2 { - // nesting1 field1; - // vec4 field2; - // }; - // For type "nesting2", this method would return 2 -- the number - // of structures through which indirection must occur to reach the - // deepest field (nesting2.field1.position). - int getDeepestStructNesting() const { - return structure ? structure->deepestNesting() : 0; - } - - bool isStructureContainingArrays() const { - return structure ? structure->containsArrays() : false; - } - -private: - TString buildMangledName() const; - - TBasicType type; - TPrecision precision; - TQualifier qualifier; - unsigned char size; - bool matrix; - bool array; - int arraySize; - - TStructure* structure; // 0 unless this is a struct - - mutable TString mangled; -}; - -// -// This is a workaround for a problem with the yacc stack, It can't have -// types that it thinks have non-trivial constructors. It should -// just be used while recognizing the grammar, not anything else. Pointers -// could be used, but also trying to avoid lots of memory management overhead. -// -// Not as bad as it looks, there is no actual assumption that the fields -// match up or are name the same or anything like that. -// -struct TPublicType -{ - TBasicType type; - TQualifier qualifier; - TPrecision precision; - unsigned char size; // size of vector or matrix, not size of array - bool matrix; - bool array; - int arraySize; - TType* userDef; - TSourceLoc line; - - void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln) - { - type = bt; - qualifier = q; - precision = EbpUndefined; - size = 1; - matrix = false; - array = false; - arraySize = 0; - userDef = 0; - line = ln; - } - - void setAggregate(unsigned char s, bool m = false) - { - size = s; - matrix = m; - } - - void setArray(bool a, int s = 0) - { - array = a; - arraySize = s; - } - - bool isStructureContainingArrays() const - { - if (!userDef) - { - return false; - } - - return userDef->isStructureContainingArrays(); - } -}; - -#endif // _TYPES_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/Uniform.cpp b/chromium/third_party/angle/src/compiler/Uniform.cpp deleted file mode 100644 index f367db2be8e..00000000000 --- a/chromium/third_party/angle/src/compiler/Uniform.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/Uniform.h" - -namespace sh -{ - -Uniform::Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex) -{ - this->type = type; - this->precision = precision; - this->name = name; - this->arraySize = arraySize; - this->registerIndex = registerIndex; -} - -} diff --git a/chromium/third_party/angle/src/compiler/Uniform.h b/chromium/third_party/angle/src/compiler/Uniform.h deleted file mode 100644 index 4c53ffa7d2f..00000000000 --- a/chromium/third_party/angle/src/compiler/Uniform.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_UNIFORM_H_ -#define COMPILER_UNIFORM_H_ - -#include <string> -#include <vector> - -#define GL_APICALL -#include <GLES2/gl2.h> - -namespace sh -{ - -struct Uniform -{ - Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex); - - GLenum type; - GLenum precision; - std::string name; - unsigned int arraySize; - - int registerIndex; -}; - -typedef std::vector<Uniform> ActiveUniforms; - -} - -#endif // COMPILER_UNIFORM_H_ diff --git a/chromium/third_party/angle/src/compiler/ValidateLimitations.h b/chromium/third_party/angle/src/compiler/ValidateLimitations.h deleted file mode 100644 index a835cb3c226..00000000000 --- a/chromium/third_party/angle/src/compiler/ValidateLimitations.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "GLSLANG/ShaderLang.h" -#include "compiler/intermediate.h" - -class TInfoSinkBase; - -struct TLoopInfo { - struct TIndex { - int id; // symbol id. - } index; - TIntermLoop* loop; -}; -typedef TVector<TLoopInfo> TLoopStack; - -// Traverses intermediate tree to ensure that the shader does not exceed the -// minimum functionality mandated in GLSL 1.0 spec, Appendix A. -class ValidateLimitations : public TIntermTraverser { -public: - ValidateLimitations(ShShaderType shaderType, TInfoSinkBase& sink); - - int numErrors() const { return mNumErrors; } - - virtual bool visitBinary(Visit, TIntermBinary*); - virtual bool visitUnary(Visit, TIntermUnary*); - virtual bool visitAggregate(Visit, TIntermAggregate*); - virtual bool visitLoop(Visit, TIntermLoop*); - -private: - void error(TSourceLoc loc, const char *reason, const char* token); - - bool withinLoopBody() const; - bool isLoopIndex(const TIntermSymbol* symbol) const; - bool validateLoopType(TIntermLoop* node); - bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info); - bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info); - bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info); - bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info); - // Returns true if none of the loop indices is used as the argument to - // the given function out or inout parameter. - bool validateFunctionCall(TIntermAggregate* node); - bool validateOperation(TIntermOperator* node, TIntermNode* operand); - - // Returns true if indexing does not exceed the minimum functionality - // mandated in GLSL 1.0 spec, Appendix A, Section 5. - bool isConstExpr(TIntermNode* node); - bool isConstIndexExpr(TIntermNode* node); - bool validateIndexing(TIntermBinary* node); - - ShShaderType mShaderType; - TInfoSinkBase& mSink; - int mNumErrors; - TLoopStack mLoopStack; -}; - diff --git a/chromium/third_party/angle/src/compiler/glslang.l b/chromium/third_party/angle/src/compiler/glslang.l deleted file mode 100644 index 430f8ca13bc..00000000000 --- a/chromium/third_party/angle/src/compiler/glslang.l +++ /dev/null @@ -1,355 +0,0 @@ -/* -// -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -This file contains the Lex specification for GLSL ES. -Based on ANSI C grammar, Lex specification: -http://www.lysator.liu.se/c/ANSI-C-grammar-l.html - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, -WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). -*/ - -%top{ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! - -// Ignore errors in auto-generated code. -#if defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wswitch-enum" -#elif defined(_MSC_VER) -#pragma warning(disable: 4065) -#pragma warning(disable: 4189) -#pragma warning(disable: 4505) -#pragma warning(disable: 4701) -#endif -} - -%{ -#include "compiler/glslang.h" -#include "compiler/ParseContext.h" -#include "compiler/preprocessor/Token.h" -#include "compiler/util.h" -#include "glslang_tab.h" - -/* windows only pragma */ -#ifdef _MSC_VER -#pragma warning(disable : 4102) -#endif - -#define YY_USER_ACTION \ - yylloc->first_file = yylloc->last_file = yycolumn; \ - yylloc->first_line = yylloc->last_line = yylineno; - -#define YY_INPUT(buf, result, max_size) \ - result = string_input(buf, max_size, yyscanner); - -static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner); -static int check_type(yyscan_t yyscanner); -static int reserved_word(yyscan_t yyscanner); -static int int_constant(yyscan_t yyscanner); -static int float_constant(yyscan_t yyscanner); -%} - -%option noyywrap nounput never-interactive -%option yylineno reentrant bison-bridge bison-locations -%option extra-type="TParseContext*" - -D [0-9] -L [a-zA-Z_] -H [a-fA-F0-9] -E [Ee][+-]?{D}+ -O [0-7] - -%% - -"invariant" { return INVARIANT; } -"highp" { return HIGH_PRECISION; } -"mediump" { return MEDIUM_PRECISION; } -"lowp" { return LOW_PRECISION; } -"precision" { return PRECISION; } - -"attribute" { return ATTRIBUTE; } -"const" { return CONST_QUAL; } -"uniform" { return UNIFORM; } -"varying" { return VARYING; } - -"break" { return BREAK; } -"continue" { return CONTINUE; } -"do" { return DO; } -"for" { return FOR; } -"while" { return WHILE; } - -"if" { return IF; } -"else" { return ELSE; } - -"in" { return IN_QUAL; } -"out" { return OUT_QUAL; } -"inout" { return INOUT_QUAL; } - -"float" { return FLOAT_TYPE; } -"int" { return INT_TYPE; } -"void" { return VOID_TYPE; } -"bool" { return BOOL_TYPE; } -"true" { yylval->lex.b = true; return BOOLCONSTANT; } -"false" { yylval->lex.b = false; return BOOLCONSTANT; } - -"discard" { return DISCARD; } -"return" { return RETURN; } - -"mat2" { return MATRIX2; } -"mat3" { return MATRIX3; } -"mat4" { return MATRIX4; } - -"vec2" { return VEC2; } -"vec3" { return VEC3; } -"vec4" { return VEC4; } -"ivec2" { return IVEC2; } -"ivec3" { return IVEC3; } -"ivec4" { return IVEC4; } -"bvec2" { return BVEC2; } -"bvec3" { return BVEC3; } -"bvec4" { return BVEC4; } - -"sampler2D" { return SAMPLER2D; } -"samplerCube" { return SAMPLERCUBE; } -"samplerExternalOES" { return SAMPLER_EXTERNAL_OES; } -"sampler2DRect" { return SAMPLER2DRECT; } - -"struct" { return STRUCT; } - -"asm" { return reserved_word(yyscanner); } - -"class" { return reserved_word(yyscanner); } -"union" { return reserved_word(yyscanner); } -"enum" { return reserved_word(yyscanner); } -"typedef" { return reserved_word(yyscanner); } -"template" { return reserved_word(yyscanner); } -"this" { return reserved_word(yyscanner); } -"packed" { return reserved_word(yyscanner); } - -"goto" { return reserved_word(yyscanner); } -"switch" { return reserved_word(yyscanner); } -"default" { return reserved_word(yyscanner); } - -"inline" { return reserved_word(yyscanner); } -"noinline" { return reserved_word(yyscanner); } -"volatile" { return reserved_word(yyscanner); } -"public" { return reserved_word(yyscanner); } -"static" { return reserved_word(yyscanner); } -"extern" { return reserved_word(yyscanner); } -"external" { return reserved_word(yyscanner); } -"interface" { return reserved_word(yyscanner); } -"flat" { return reserved_word(yyscanner); } - -"long" { return reserved_word(yyscanner); } -"short" { return reserved_word(yyscanner); } -"double" { return reserved_word(yyscanner); } -"half" { return reserved_word(yyscanner); } -"fixed" { return reserved_word(yyscanner); } -"unsigned" { return reserved_word(yyscanner); } -"superp" { return reserved_word(yyscanner); } - -"input" { return reserved_word(yyscanner); } -"output" { return reserved_word(yyscanner); } - -"hvec2" { return reserved_word(yyscanner); } -"hvec3" { return reserved_word(yyscanner); } -"hvec4" { return reserved_word(yyscanner); } -"dvec2" { return reserved_word(yyscanner); } -"dvec3" { return reserved_word(yyscanner); } -"dvec4" { return reserved_word(yyscanner); } -"fvec2" { return reserved_word(yyscanner); } -"fvec3" { return reserved_word(yyscanner); } -"fvec4" { return reserved_word(yyscanner); } - -"sampler1D" { return reserved_word(yyscanner); } -"sampler3D" { return reserved_word(yyscanner); } -"sampler1DShadow" { return reserved_word(yyscanner); } -"sampler2DShadow" { return reserved_word(yyscanner); } -"sampler3DRect" { return reserved_word(yyscanner); } -"sampler2DRectShadow" { return reserved_word(yyscanner); } - -"sizeof" { return reserved_word(yyscanner); } -"cast" { return reserved_word(yyscanner); } - -"namespace" { return reserved_word(yyscanner); } -"using" { return reserved_word(yyscanner); } - -{L}({L}|{D})* { - yylval->lex.string = NewPoolTString(yytext); - return check_type(yyscanner); -} - -0[xX]{H}+ { return int_constant(yyscanner); } -0{O}+ { return int_constant(yyscanner); } -{D}+ { return int_constant(yyscanner); } - -{D}+{E} { return float_constant(yyscanner); } -{D}+"."{D}*({E})? { return float_constant(yyscanner); } -"."{D}+({E})? { return float_constant(yyscanner); } - -"+=" { return ADD_ASSIGN; } -"-=" { return SUB_ASSIGN; } -"*=" { return MUL_ASSIGN; } -"/=" { return DIV_ASSIGN; } -"%=" { return MOD_ASSIGN; } -"<<=" { return LEFT_ASSIGN; } -">>=" { return RIGHT_ASSIGN; } -"&=" { return AND_ASSIGN; } -"^=" { return XOR_ASSIGN; } -"|=" { return OR_ASSIGN; } - -"++" { return INC_OP; } -"--" { return DEC_OP; } -"&&" { return AND_OP; } -"||" { return OR_OP; } -"^^" { return XOR_OP; } -"<=" { return LE_OP; } -">=" { return GE_OP; } -"==" { return EQ_OP; } -"!=" { return NE_OP; } -"<<" { return LEFT_OP; } -">>" { return RIGHT_OP; } -";" { return SEMICOLON; } -("{"|"<%") { return LEFT_BRACE; } -("}"|"%>") { return RIGHT_BRACE; } -"," { return COMMA; } -":" { return COLON; } -"=" { return EQUAL; } -"(" { return LEFT_PAREN; } -")" { return RIGHT_PAREN; } -("["|"<:") { return LEFT_BRACKET; } -("]"|":>") { return RIGHT_BRACKET; } -"." { return DOT; } -"!" { return BANG; } -"-" { return DASH; } -"~" { return TILDE; } -"+" { return PLUS; } -"*" { return STAR; } -"/" { return SLASH; } -"%" { return PERCENT; } -"<" { return LEFT_ANGLE; } -">" { return RIGHT_ANGLE; } -"|" { return VERTICAL_BAR; } -"^" { return CARET; } -"&" { return AMPERSAND; } -"?" { return QUESTION; } - -[ \t\v\n\f\r] { } -<<EOF>> { yyterminate(); } -. { assert(false); return 0; } - -%% - -yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { - pp::Token token; - yyget_extra(yyscanner)->preprocessor.lex(&token); - yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); - if (len < max_size) - memcpy(buf, token.text.c_str(), len); - yyset_column(token.location.file, yyscanner); - yyset_lineno(token.location.line, yyscanner); - - if (len >= max_size) - YY_FATAL_ERROR("Input buffer overflow"); - else if (len > 0) - buf[len++] = ' '; - return len; -} - -int check_type(yyscan_t yyscanner) { - struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - - int token = IDENTIFIER; - TSymbol* symbol = yyextra->symbolTable.find(yytext); - if (symbol && symbol->isVariable()) { - TVariable* variable = static_cast<TVariable*>(symbol); - if (variable->isUserType()) - token = TYPE_NAME; - } - yylval->lex.symbol = symbol; - return token; -} - -int reserved_word(yyscan_t yyscanner) { - struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - - yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); - yyextra->recover(); - return 0; -} - -void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) { - context->error(*lloc, reason, yyget_text(context->scanner)); - context->recover(); -} - -int int_constant(yyscan_t yyscanner) { - struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - - if (!atoi_clamp(yytext, &(yylval->lex.i))) - yyextra->warning(*yylloc, "Integer overflow", yytext, ""); - return INTCONSTANT; -} - -int float_constant(yyscan_t yyscanner) { - struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - - if (!atof_clamp(yytext, &(yylval->lex.f))) - yyextra->warning(*yylloc, "Float overflow", yytext, ""); - return FLOATCONSTANT; -} - -int glslang_initialize(TParseContext* context) { - yyscan_t scanner = NULL; - if (yylex_init_extra(context, &scanner)) - return 1; - - context->scanner = scanner; - return 0; -} - -int glslang_finalize(TParseContext* context) { - yyscan_t scanner = context->scanner; - if (scanner == NULL) return 0; - - context->scanner = NULL; - yylex_destroy(scanner); - - return 0; -} - -int glslang_scan(size_t count, const char* const string[], const int length[], - TParseContext* context) { - yyrestart(NULL, context->scanner); - yyset_column(0, context->scanner); - yyset_lineno(1, context->scanner); - - // Initialize preprocessor. - if (!context->preprocessor.init(count, string, length)) - return 1; - context->preprocessor.setMaxTokenLength(SH_MAX_TOKEN_LENGTH); - - // Define extension macros. - const TExtensionBehavior& extBehavior = context->extensionBehavior(); - for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); - iter != extBehavior.end(); ++iter) { - context->preprocessor.predefineMacro(iter->first.c_str(), 1); - } - if (context->fragmentPrecisionHigh) - context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); - - return 0; -} - diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp index a7ce862bcb4..cf60bc2349d 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp @@ -16,8 +16,8 @@ Diagnostics::~Diagnostics() } void Diagnostics::report(ID id, - const SourceLocation& loc, - const std::string& text) + const SourceLocation &loc, + const std::string &text) { // TODO(alokp): Keep a count of errors and warnings. print(id, loc, text); @@ -41,86 +41,86 @@ std::string Diagnostics::message(ID id) { // Errors begin. case PP_INTERNAL_ERROR: - return "internal error"; + return "internal error"; case PP_OUT_OF_MEMORY: - return "out of memory"; + return "out of memory"; case PP_INVALID_CHARACTER: - return "invalid character"; + return "invalid character"; case PP_INVALID_NUMBER: - return "invalid number"; + return "invalid number"; case PP_INTEGER_OVERFLOW: - return "integer overflow"; + return "integer overflow"; case PP_FLOAT_OVERFLOW: - return "float overflow"; + return "float overflow"; case PP_TOKEN_TOO_LONG: - return "token too long"; + return "token too long"; case PP_INVALID_EXPRESSION: - return "invalid expression"; + return "invalid expression"; case PP_DIVISION_BY_ZERO: - return "division by zero"; + return "division by zero"; case PP_EOF_IN_COMMENT: - return "unexpected end of file found in comment"; + return "unexpected end of file found in comment"; case PP_UNEXPECTED_TOKEN: - return "unexpected token"; + return "unexpected token"; case PP_DIRECTIVE_INVALID_NAME: - return "invalid directive name"; + return "invalid directive name"; case PP_MACRO_NAME_RESERVED: - return "macro name is reserved"; + return "macro name is reserved"; case PP_MACRO_REDEFINED: - return "macro redefined"; + return "macro redefined"; case PP_MACRO_PREDEFINED_REDEFINED: - return "predefined macro redefined"; + return "predefined macro redefined"; case PP_MACRO_PREDEFINED_UNDEFINED: - return "predefined macro undefined"; + return "predefined macro undefined"; case PP_MACRO_UNTERMINATED_INVOCATION: - return "unterminated macro invocation"; + return "unterminated macro invocation"; case PP_MACRO_TOO_FEW_ARGS: - return "Not enough arguments for macro"; + return "Not enough arguments for macro"; case PP_MACRO_TOO_MANY_ARGS: - return "Too many arguments for macro"; + return "Too many arguments for macro"; case PP_CONDITIONAL_ENDIF_WITHOUT_IF: - return "unexpected #endif found without a matching #if"; + return "unexpected #endif found without a matching #if"; case PP_CONDITIONAL_ELSE_WITHOUT_IF: - return "unexpected #else found without a matching #if"; + return "unexpected #else found without a matching #if"; case PP_CONDITIONAL_ELSE_AFTER_ELSE: - return "unexpected #else found after another #else"; + return "unexpected #else found after another #else"; case PP_CONDITIONAL_ELIF_WITHOUT_IF: - return "unexpected #elif found without a matching #if"; + return "unexpected #elif found without a matching #if"; case PP_CONDITIONAL_ELIF_AFTER_ELSE: - return "unexpected #elif found after #else"; + return "unexpected #elif found after #else"; case PP_CONDITIONAL_UNTERMINATED: - return "unexpected end of file found in conditional block"; + return "unexpected end of file found in conditional block"; case PP_INVALID_EXTENSION_NAME: - return "invalid extension name"; + return "invalid extension name"; case PP_INVALID_EXTENSION_BEHAVIOR: - return "invalid extension behavior"; + return "invalid extension behavior"; case PP_INVALID_EXTENSION_DIRECTIVE: - return "invalid extension directive"; + return "invalid extension directive"; case PP_INVALID_VERSION_NUMBER: - return "invalid version number"; + return "invalid version number"; case PP_INVALID_VERSION_DIRECTIVE: - return "invalid version directive"; + return "invalid version directive"; case PP_VERSION_NOT_FIRST_STATEMENT: return "#version directive must occur before anything else, " "except for comments and white space"; case PP_INVALID_LINE_NUMBER: - return "invalid line number"; + return "invalid line number"; case PP_INVALID_FILE_NUMBER: - return "invalid file number"; + return "invalid file number"; case PP_INVALID_LINE_DIRECTIVE: - return "invalid line directive"; + return "invalid line directive"; // Errors end. // Warnings begin. case PP_EOF_IN_DIRECTIVE: - return "unexpected end of file found in directive"; + return "unexpected end of file found in directive"; case PP_CONDITIONAL_UNEXPECTED_TOKEN: - return "unexpected token after conditional expression"; + return "unexpected token after conditional expression"; case PP_UNRECOGNIZED_PRAGMA: - return "unrecognized pragma"; + return "unrecognized pragma"; // Warnings end. default: - assert(false); - return ""; + assert(false); + return ""; } } diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h index 2c8c539137b..a7587ed6577 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h @@ -72,15 +72,15 @@ class Diagnostics virtual ~Diagnostics(); - void report(ID id, const SourceLocation& loc, const std::string& text); + void report(ID id, const SourceLocation &loc, const std::string &text); protected: Severity severity(ID id); std::string message(ID id); virtual void print(ID id, - const SourceLocation& loc, - const std::string& text) = 0; + const SourceLocation &loc, + const std::string &text) = 0; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.h index 2aaeec28180..040b25c6a24 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.h @@ -23,19 +23,19 @@ class DirectiveHandler public: virtual ~DirectiveHandler(); - virtual void handleError(const SourceLocation& loc, - const std::string& msg) = 0; + virtual void handleError(const SourceLocation &loc, + const std::string &msg) = 0; // Handle pragma of form: #pragma name[(value)] - virtual void handlePragma(const SourceLocation& loc, - const std::string& name, - const std::string& value) = 0; + virtual void handlePragma(const SourceLocation &loc, + const std::string &name, + const std::string &value) = 0; - virtual void handleExtension(const SourceLocation& loc, - const std::string& name, - const std::string& behavior) = 0; + virtual void handleExtension(const SourceLocation &loc, + const std::string &name, + const std::string &behavior) = 0; - virtual void handleVersion(const SourceLocation& loc, + virtual void handleVersion(const SourceLocation &loc, int version) = 0; }; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp index ebec79804dc..6434d5cb5c8 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -35,9 +35,8 @@ enum DirectiveType DIRECTIVE_VERSION, DIRECTIVE_LINE }; -} // namespace -static DirectiveType getDirective(const pp::Token* token) +DirectiveType getDirective(const pp::Token *token) { static const std::string kDirectiveDefine("define"); static const std::string kDirectiveUndef("undef"); @@ -58,35 +57,35 @@ static DirectiveType getDirective(const pp::Token* token) if (token->text == kDirectiveDefine) return DIRECTIVE_DEFINE; - else if (token->text == kDirectiveUndef) + if (token->text == kDirectiveUndef) return DIRECTIVE_UNDEF; - else if (token->text == kDirectiveIf) + if (token->text == kDirectiveIf) return DIRECTIVE_IF; - else if (token->text == kDirectiveIfdef) + if (token->text == kDirectiveIfdef) return DIRECTIVE_IFDEF; - else if (token->text == kDirectiveIfndef) + if (token->text == kDirectiveIfndef) return DIRECTIVE_IFNDEF; - else if (token->text == kDirectiveElse) + if (token->text == kDirectiveElse) return DIRECTIVE_ELSE; - else if (token->text == kDirectiveElif) + if (token->text == kDirectiveElif) return DIRECTIVE_ELIF; - else if (token->text == kDirectiveEndif) + if (token->text == kDirectiveEndif) return DIRECTIVE_ENDIF; - else if (token->text == kDirectiveError) + if (token->text == kDirectiveError) return DIRECTIVE_ERROR; - else if (token->text == kDirectivePragma) + if (token->text == kDirectivePragma) return DIRECTIVE_PRAGMA; - else if (token->text == kDirectiveExtension) + if (token->text == kDirectiveExtension) return DIRECTIVE_EXTENSION; - else if (token->text == kDirectiveVersion) + if (token->text == kDirectiveVersion) return DIRECTIVE_VERSION; - else if (token->text == kDirectiveLine) + if (token->text == kDirectiveLine) return DIRECTIVE_LINE; return DIRECTIVE_NONE; } -static bool isConditionalDirective(DirectiveType directive) +bool isConditionalDirective(DirectiveType directive) { switch (directive) { @@ -103,12 +102,12 @@ static bool isConditionalDirective(DirectiveType directive) } // Returns true if the token represents End Of Directive. -static bool isEOD(const pp::Token* token) +bool isEOD(const pp::Token *token) { return (token->type == '\n') || (token->type == pp::Token::LAST); } -static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token) +void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) { while(!isEOD(token)) { @@ -116,7 +115,7 @@ static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token) } } -static bool isMacroNameReserved(const std::string& name) +bool isMacroNameReserved(const std::string &name) { // Names prefixed with "GL_" are reserved. if (name.substr(0, 3) == "GL_") @@ -129,30 +128,32 @@ static bool isMacroNameReserved(const std::string& name) return false; } -static bool isMacroPredefined(const std::string& name, - const pp::MacroSet& macroSet) +bool isMacroPredefined(const std::string &name, + const pp::MacroSet ¯oSet) { pp::MacroSet::const_iterator iter = macroSet.find(name); return iter != macroSet.end() ? iter->second.predefined : false; } +} // namespace anonymous + namespace pp { class DefinedParser : public Lexer { public: - DefinedParser(Lexer* lexer, - const MacroSet* macroSet, - Diagnostics* diagnostics) : - mLexer(lexer), - mMacroSet(macroSet), - mDiagnostics(diagnostics) + DefinedParser(Lexer *lexer, + const MacroSet *macroSet, + Diagnostics *diagnostics) + : mLexer(lexer), + mMacroSet(macroSet), + mDiagnostics(diagnostics) { } protected: - virtual void lex(Token* token) + virtual void lex(Token *token) { static const std::string kDefined("defined"); @@ -199,24 +200,24 @@ class DefinedParser : public Lexer } private: - Lexer* mLexer; - const MacroSet* mMacroSet; - Diagnostics* mDiagnostics; + Lexer *mLexer; + const MacroSet *mMacroSet; + Diagnostics *mDiagnostics; }; -DirectiveParser::DirectiveParser(Tokenizer* tokenizer, - MacroSet* macroSet, - Diagnostics* diagnostics, - DirectiveHandler* directiveHandler) : - mPastFirstStatement(false), - mTokenizer(tokenizer), - mMacroSet(macroSet), - mDiagnostics(diagnostics), - mDirectiveHandler(directiveHandler) +DirectiveParser::DirectiveParser(Tokenizer *tokenizer, + MacroSet *macroSet, + Diagnostics *diagnostics, + DirectiveHandler *directiveHandler) + : mPastFirstStatement(false), + mTokenizer(tokenizer), + mMacroSet(macroSet), + mDiagnostics(diagnostics), + mDirectiveHandler(directiveHandler) { } -void DirectiveParser::lex(Token* token) +void DirectiveParser::lex(Token *token) { do { @@ -232,19 +233,20 @@ void DirectiveParser::lex(Token* token) { if (!mConditionalStack.empty()) { - const ConditionalBlock& block = mConditionalStack.back(); + const ConditionalBlock &block = mConditionalStack.back(); mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, block.location, block.type); } break; } - } while (skipping() || (token->type == '\n')); + } + while (skipping() || (token->type == '\n')); mPastFirstStatement = true; } -void DirectiveParser::parseDirective(Token* token) +void DirectiveParser::parseDirective(Token *token) { assert(token->type == Token::PP_HASH); @@ -324,7 +326,7 @@ void DirectiveParser::parseDirective(Token* token) } } -void DirectiveParser::parseDefine(Token* token) +void DirectiveParser::parseDefine(Token *token) { assert(getDirective(token) == DIRECTIVE_DEFINE); @@ -357,14 +359,16 @@ void DirectiveParser::parseDefine(Token* token) { // Function-like macro. Collect arguments. macro.type = Macro::kTypeFunc; - do { + do + { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; macro.parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. - } while (token->type == ','); + } + while (token->type == ','); if (token->type != ')') { @@ -404,7 +408,7 @@ void DirectiveParser::parseDefine(Token* token) mMacroSet->insert(std::make_pair(macro.name, macro)); } -void DirectiveParser::parseUndef(Token* token) +void DirectiveParser::parseUndef(Token *token) { assert(getDirective(token) == DIRECTIVE_UNDEF); @@ -433,25 +437,25 @@ void DirectiveParser::parseUndef(Token* token) mTokenizer->lex(token); } -void DirectiveParser::parseIf(Token* token) +void DirectiveParser::parseIf(Token *token) { assert(getDirective(token) == DIRECTIVE_IF); parseConditionalIf(token); } -void DirectiveParser::parseIfdef(Token* token) +void DirectiveParser::parseIfdef(Token *token) { assert(getDirective(token) == DIRECTIVE_IFDEF); parseConditionalIf(token); } -void DirectiveParser::parseIfndef(Token* token) +void DirectiveParser::parseIfndef(Token *token) { assert(getDirective(token) == DIRECTIVE_IFNDEF); parseConditionalIf(token); } -void DirectiveParser::parseElse(Token* token) +void DirectiveParser::parseElse(Token *token) { assert(getDirective(token) == DIRECTIVE_ELSE); @@ -463,7 +467,7 @@ void DirectiveParser::parseElse(Token* token) return; } - ConditionalBlock& block = mConditionalStack.back(); + ConditionalBlock &block = mConditionalStack.back(); if (block.skipBlock) { // No diagnostics. Just skip the whole line. @@ -492,7 +496,7 @@ void DirectiveParser::parseElse(Token* token) } } -void DirectiveParser::parseElif(Token* token) +void DirectiveParser::parseElif(Token *token) { assert(getDirective(token) == DIRECTIVE_ELIF); @@ -504,7 +508,7 @@ void DirectiveParser::parseElif(Token* token) return; } - ConditionalBlock& block = mConditionalStack.back(); + ConditionalBlock &block = mConditionalStack.back(); if (block.skipBlock) { // No diagnostics. Just skip the whole line. @@ -532,7 +536,7 @@ void DirectiveParser::parseElif(Token* token) block.foundValidGroup = expression != 0; } -void DirectiveParser::parseEndif(Token* token) +void DirectiveParser::parseEndif(Token *token) { assert(getDirective(token) == DIRECTIVE_ENDIF); @@ -556,7 +560,7 @@ void DirectiveParser::parseEndif(Token* token) } } -void DirectiveParser::parseError(Token* token) +void DirectiveParser::parseError(Token *token) { assert(getDirective(token) == DIRECTIVE_ERROR); @@ -571,7 +575,7 @@ void DirectiveParser::parseError(Token* token) } // Parses pragma of form: #pragma name[(value)]. -void DirectiveParser::parsePragma(Token* token) +void DirectiveParser::parsePragma(Token *token) { assert(getDirective(token) == DIRECTIVE_PRAGMA); @@ -627,7 +631,7 @@ void DirectiveParser::parsePragma(Token* token) } } -void DirectiveParser::parseExtension(Token* token) +void DirectiveParser::parseExtension(Token *token) { assert(getDirective(token) == DIRECTIVE_EXTENSION); @@ -694,7 +698,7 @@ void DirectiveParser::parseExtension(Token* token) mDirectiveHandler->handleExtension(token->location, name, behavior); } -void DirectiveParser::parseVersion(Token* token) +void DirectiveParser::parseVersion(Token *token) { assert(getDirective(token) == DIRECTIVE_VERSION); @@ -708,7 +712,9 @@ void DirectiveParser::parseVersion(Token* token) enum State { - VERSION_NUMBER + VERSION_NUMBER, + VERSION_PROFILE, + VERSION_ENDLINE }; bool valid = true; @@ -716,12 +722,12 @@ void DirectiveParser::parseVersion(Token* token) int state = VERSION_NUMBER; mTokenizer->lex(token); - while ((token->type != '\n') && (token->type != Token::LAST)) + while (valid && (token->type != '\n') && (token->type != Token::LAST)) { - switch (state++) + switch (state) { case VERSION_NUMBER: - if (valid && (token->type != Token::CONST_INT)) + if (token->type != Token::CONST_INT) { mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, token->location, token->text); @@ -733,29 +739,44 @@ void DirectiveParser::parseVersion(Token* token) token->location, token->text); valid = false; } - break; - default: if (valid) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, + state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; + } + break; + case VERSION_PROFILE: + if (token->type != Token::IDENTIFIER || token->text != "es") + { + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, token->text); valid = false; } + state = VERSION_ENDLINE; + break; + default: + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, + token->location, token->text); + valid = false; break; } + mTokenizer->lex(token); } - if (valid && (state != VERSION_NUMBER + 1)) + + if (valid && (state != VERSION_ENDLINE)) { mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, token->text); valid = false; } + if (valid) + { mDirectiveHandler->handleVersion(token->location, version); + } } -void DirectiveParser::parseLine(Token* token) +void DirectiveParser::parseLine(Token *token) { assert(getDirective(token) == DIRECTIVE_LINE); @@ -824,19 +845,21 @@ void DirectiveParser::parseLine(Token* token) if (valid) { mTokenizer->setLineNumber(line); - if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file); + if (state == FILE_NUMBER + 1) + mTokenizer->setFileNumber(file); } } bool DirectiveParser::skipping() const { - if (mConditionalStack.empty()) return false; + if (mConditionalStack.empty()) + return false; const ConditionalBlock& block = mConditionalStack.back(); return block.skipBlock || block.skipGroup; } -void DirectiveParser::parseConditionalIf(Token* token) +void DirectiveParser::parseConditionalIf(Token *token) { ConditionalBlock block; block.type = token->text; @@ -877,7 +900,7 @@ void DirectiveParser::parseConditionalIf(Token* token) mConditionalStack.push_back(block); } -int DirectiveParser::parseExpressionIf(Token* token) +int DirectiveParser::parseExpressionIf(Token *token) { assert((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); @@ -901,7 +924,7 @@ int DirectiveParser::parseExpressionIf(Token* token) return expression; } -int DirectiveParser::parseExpressionIfdef(Token* token) +int DirectiveParser::parseExpressionIfdef(Token *token) { assert((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF)); diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h index 8a7f0072bae..335091781c1 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h @@ -22,35 +22,35 @@ class Tokenizer; class DirectiveParser : public Lexer { public: - DirectiveParser(Tokenizer* tokenizer, - MacroSet* macroSet, - Diagnostics* diagnostics, - DirectiveHandler* directiveHandler); + DirectiveParser(Tokenizer *tokenizer, + MacroSet *macroSet, + Diagnostics *diagnostics, + DirectiveHandler *directiveHandler); - virtual void lex(Token* token); + virtual void lex(Token *token); private: PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser); - void parseDirective(Token* token); - void parseDefine(Token* token); - void parseUndef(Token* token); - void parseIf(Token* token); - void parseIfdef(Token* token); - void parseIfndef(Token* token); - void parseElse(Token* token); - void parseElif(Token* token); - void parseEndif(Token* token); - void parseError(Token* token); - void parsePragma(Token* token); - void parseExtension(Token* token); - void parseVersion(Token* token); - void parseLine(Token* token); + void parseDirective(Token *token); + void parseDefine(Token *token); + void parseUndef(Token *token); + void parseIf(Token *token); + void parseIfdef(Token *token); + void parseIfndef(Token *token); + void parseElse(Token *token); + void parseElif(Token *token); + void parseEndif(Token *token); + void parseError(Token *token); + void parsePragma(Token *token); + void parseExtension(Token *token); + void parseVersion(Token *token); + void parseLine(Token *token); bool skipping() const; - void parseConditionalIf(Token* token); - int parseExpressionIf(Token* token); - int parseExpressionIfdef(Token* token); + void parseConditionalIf(Token *token); + int parseExpressionIf(Token *token); + int parseExpressionIfdef(Token *token); struct ConditionalBlock { @@ -61,20 +61,20 @@ class DirectiveParser : public Lexer bool foundValidGroup; bool foundElseGroup; - ConditionalBlock() : - skipBlock(false), - skipGroup(false), - foundValidGroup(false), - foundElseGroup(false) + ConditionalBlock() + : skipBlock(false), + skipGroup(false), + foundValidGroup(false), + foundElseGroup(false) { } }; bool mPastFirstStatement; std::vector<ConditionalBlock> mConditionalStack; - Tokenizer* mTokenizer; - MacroSet* mMacroSet; - Diagnostics* mDiagnostics; - DirectiveHandler* mDirectiveHandler; + Tokenizer *mTokenizer; + MacroSet *mMacroSet; + Diagnostics *mDiagnostics; + DirectiveHandler *mDirectiveHandler; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp index 2d374961845..f4126380876 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.7. */ +/* A Bison parser, made by GNU Bison 2.7.1. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.7" +#define YYBISON_VERSION "2.7.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -264,6 +264,14 @@ typedef short int yytype_int16; # endif #endif +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ +# endif +#endif + /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -271,6 +279,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif + /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(N) (N) @@ -501,9 +510,9 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 91, 91, 98, 99, 102, 105, 108, 111, 114, - 117, 120, 123, 126, 129, 132, 135, 138, 141, 144, - 157, 170, 173, 176, 179, 182, 185 + 0, 97, 97, 104, 105, 108, 111, 114, 117, 120, + 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, + 163, 176, 179, 182, 185, 188, 191 }; #endif @@ -768,11 +777,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, context) # else YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -1166,12 +1171,7 @@ yydestruct (yymsg, yytype, yyvaluep, context) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YYUSE (yytype); } @@ -1891,15 +1891,14 @@ yyreturn: -int yylex(YYSTYPE* lvalp, Context* context) +int yylex(YYSTYPE *lvalp, Context *context) { int type = 0; - pp::Token* token = context->token; + pp::Token *token = context->token; switch (token->type) { - case pp::Token::CONST_INT: - { + case pp::Token::CONST_INT: { unsigned int val = 0; if (!token->uValue(&val)) { @@ -1910,39 +1909,59 @@ int yylex(YYSTYPE* lvalp, Context* context) type = TOK_CONST_INT; break; } - case pp::Token::OP_OR: type = TOK_OP_OR; break; - case pp::Token::OP_AND: type = TOK_OP_AND; break; - case pp::Token::OP_NE: type = TOK_OP_NE; break; - case pp::Token::OP_EQ: type = TOK_OP_EQ; break; - case pp::Token::OP_GE: type = TOK_OP_GE; break; - case pp::Token::OP_LE: type = TOK_OP_LE; break; - case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; - case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; - case '|': type = '|'; break; - case '^': type = '^'; break; - case '&': type = '&'; break; - case '>': type = '>'; break; - case '<': type = '<'; break; - case '-': type = '-'; break; - case '+': type = '+'; break; - case '%': type = '%'; break; - case '/': type = '/'; break; - case '*': type = '*'; break; - case '!': type = '!'; break; - case '~': type = '~'; break; - case '(': type = '('; break; - case ')': type = ')'; break; + case pp::Token::OP_OR: + type = TOK_OP_OR; + break; + case pp::Token::OP_AND: + type = TOK_OP_AND; + break; + case pp::Token::OP_NE: + type = TOK_OP_NE; + break; + case pp::Token::OP_EQ: + type = TOK_OP_EQ; + break; + case pp::Token::OP_GE: + type = TOK_OP_GE; + break; + case pp::Token::OP_LE: + type = TOK_OP_LE; + break; + case pp::Token::OP_RIGHT: + type = TOK_OP_RIGHT; + break; + case pp::Token::OP_LEFT: + type = TOK_OP_LEFT; + break; + case '|': + case '^': + case '&': + case '>': + case '<': + case '-': + case '+': + case '%': + case '/': + case '*': + case '!': + case '~': + case '(': + case ')': + type = token->type; + break; - default: break; + default: + break; } // Advance to the next token if the current one is valid. - if (type != 0) context->lexer->lex(token); + if (type != 0) + context->lexer->lex(token); return type; } -void yyerror(Context* context, const char* reason) +void yyerror(Context *context, const char *reason) { context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION, context->token->location, @@ -1951,13 +1970,13 @@ void yyerror(Context* context, const char* reason) namespace pp { -ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : - mLexer(lexer), - mDiagnostics(diagnostics) +ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics) + : mLexer(lexer), + mDiagnostics(diagnostics) { } -bool ExpressionParser::parse(Token* token, int* result) +bool ExpressionParser::parse(Token *token, int *result) { Context context; context.diagnostics = mDiagnostics; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h index 092d059413b..f040cb01fa5 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h @@ -19,15 +19,15 @@ struct Token; class ExpressionParser { public: - ExpressionParser(Lexer* lexer, Diagnostics* diagnostics); + ExpressionParser(Lexer *lexer, Diagnostics *diagnostics); - bool parse(Token* token, int* result); + bool parse(Token *token, int *result); private: PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser); - Lexer* mLexer; - Diagnostics* mDiagnostics; + Lexer *mLexer; + Diagnostics *mDiagnostics; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y index 27ed6ad5f2f..662a31b6500 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y +++ b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y @@ -152,7 +152,7 @@ expression std::ostringstream stream; stream << $1 << " % " << $3; std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, context->token->location, text.c_str()); YYABORT; @@ -165,7 +165,7 @@ expression std::ostringstream stream; stream << $1 << " / " << $3; std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, context->token->location, text.c_str()); YYABORT; @@ -195,73 +195,92 @@ expression %% -int yylex(YYSTYPE* lvalp, Context* context) +int yylex(YYSTYPE *lvalp, Context *context) { int type = 0; - pp::Token* token = context->token; + pp::Token *token = context->token; switch (token->type) { - case pp::Token::CONST_INT: - { + case pp::Token::CONST_INT: { unsigned int val = 0; if (!token->uValue(&val)) { - context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW, + context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); } *lvalp = static_cast<YYSTYPE>(val); type = TOK_CONST_INT; break; } - case pp::Token::OP_OR: type = TOK_OP_OR; break; - case pp::Token::OP_AND: type = TOK_OP_AND; break; - case pp::Token::OP_NE: type = TOK_OP_NE; break; - case pp::Token::OP_EQ: type = TOK_OP_EQ; break; - case pp::Token::OP_GE: type = TOK_OP_GE; break; - case pp::Token::OP_LE: type = TOK_OP_LE; break; - case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; - case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; - case '|': type = '|'; break; - case '^': type = '^'; break; - case '&': type = '&'; break; - case '>': type = '>'; break; - case '<': type = '<'; break; - case '-': type = '-'; break; - case '+': type = '+'; break; - case '%': type = '%'; break; - case '/': type = '/'; break; - case '*': type = '*'; break; - case '!': type = '!'; break; - case '~': type = '~'; break; - case '(': type = '('; break; - case ')': type = ')'; break; + case pp::Token::OP_OR: + type = TOK_OP_OR; + break; + case pp::Token::OP_AND: + type = TOK_OP_AND; + break; + case pp::Token::OP_NE: + type = TOK_OP_NE; + break; + case pp::Token::OP_EQ: + type = TOK_OP_EQ; + break; + case pp::Token::OP_GE: + type = TOK_OP_GE; + break; + case pp::Token::OP_LE: + type = TOK_OP_LE; + break; + case pp::Token::OP_RIGHT: + type = TOK_OP_RIGHT; + break; + case pp::Token::OP_LEFT: + type = TOK_OP_LEFT; + break; + case '|': + case '^': + case '&': + case '>': + case '<': + case '-': + case '+': + case '%': + case '/': + case '*': + case '!': + case '~': + case '(': + case ')': + type = token->type; + break; - default: break; + default: + break; } // Advance to the next token if the current one is valid. - if (type != 0) context->lexer->lex(token); + if (type != 0) + context->lexer->lex(token); return type; } -void yyerror(Context* context, const char* reason) +void yyerror(Context *context, const char *reason) { - context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, + context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION, context->token->location, reason); } namespace pp { -ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : - mLexer(lexer), - mDiagnostics(diagnostics) +ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics) + : mLexer(lexer), + mDiagnostics(diagnostics) { } -bool ExpressionParser::parse(Token* token, int* result) +bool ExpressionParser::parse(Token *token, int *result) { Context context; context.diagnostics = mDiagnostics; @@ -276,12 +295,12 @@ bool ExpressionParser::parse(Token* token, int* result) break; case 2: - mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); + mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, ""); break; default: assert(false); - mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); + mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, ""); break; } diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp index b4d970a97d0..f9910a6cc31 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp @@ -17,7 +17,7 @@ Input::Input() : mCount(0), mString(0) { } -Input::Input(size_t count, const char* const string[], const int length[]) : +Input::Input(size_t count, const char *const string[], const int length[]) : mCount(count), mString(string) { @@ -29,7 +29,7 @@ Input::Input(size_t count, const char* const string[], const int length[]) : } } -size_t Input::read(char* buf, size_t maxSize) +size_t Input::read(char *buf, size_t maxSize) { size_t nRead = 0; while ((nRead < maxSize) && (mReadLoc.sIndex < mCount)) diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Input.h b/chromium/third_party/angle/src/compiler/preprocessor/Input.h index 14b7597cb48..2ac4f0c1704 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Input.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Input.h @@ -18,27 +18,40 @@ class Input { public: Input(); - Input(size_t count, const char* const string[], const int length[]); + Input(size_t count, const char *const string[], const int length[]); - size_t count() const { return mCount; } - const char* string(size_t index) const { return mString[index]; } - size_t length(size_t index) const { return mLength[index]; } + size_t count() const + { + return mCount; + } + const char *string(size_t index) const + { + return mString[index]; + } + size_t length(size_t index) const + { + return mLength[index]; + } - size_t read(char* buf, size_t maxSize); + size_t read(char *buf, size_t maxSize); struct Location { size_t sIndex; // String index; size_t cIndex; // Char index. - Location() : sIndex(0), cIndex(0) { } + Location() + : sIndex(0), + cIndex(0) + { + } }; - const Location& readLoc() const { return mReadLoc; } + const Location &readLoc() const { return mReadLoc; } private: // Input. size_t mCount; - const char* const* mString; + const char * const *mString; std::vector<size_t> mLength; Location mReadLoc; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h b/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h index eb85cea8734..d42d3db7e09 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h @@ -17,7 +17,7 @@ class Lexer public: virtual ~Lexer(); - virtual void lex(Token* token) = 0; + virtual void lex(Token *token) = 0; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp index b2e3088e32b..13cb14e3dc8 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp @@ -11,7 +11,7 @@ namespace pp { -bool Macro::equals(const Macro& other) const +bool Macro::equals(const Macro &other) const { return (type == other.type) && (name == other.name) && diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Macro.h b/chromium/third_party/angle/src/compiler/preprocessor/Macro.h index 7ec01491166..b77e7bc15c2 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Macro.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Macro.h @@ -26,8 +26,13 @@ struct Macro typedef std::vector<std::string> Parameters; typedef std::vector<Token> Replacements; - Macro() : predefined(false), disabled(false), type(kTypeObj) { } - bool equals(const Macro& other) const; + Macro() + : predefined(false), + disabled(false), + type(kTypeObj) + { + } + bool equals(const Macro &other) const; bool predefined; mutable bool disabled; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp index b789260af91..d7e0c834657 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp @@ -20,13 +20,13 @@ class TokenLexer : public Lexer public: typedef std::vector<Token> TokenVector; - TokenLexer(TokenVector* tokens) + TokenLexer(TokenVector *tokens) { tokens->swap(mTokens); mIter = mTokens.begin(); } - virtual void lex(Token* token) + virtual void lex(Token *token) { if (mIter == mTokens.end()) { @@ -46,12 +46,12 @@ class TokenLexer : public Lexer TokenVector::const_iterator mIter; }; -MacroExpander::MacroExpander(Lexer* lexer, - MacroSet* macroSet, - Diagnostics* diagnostics) : - mLexer(lexer), - mMacroSet(macroSet), - mDiagnostics(diagnostics) +MacroExpander::MacroExpander(Lexer *lexer, + MacroSet *macroSet, + Diagnostics *diagnostics) + : mLexer(lexer), + mMacroSet(macroSet), + mDiagnostics(diagnostics) { } @@ -63,7 +63,7 @@ MacroExpander::~MacroExpander() } } -void MacroExpander::lex(Token* token) +void MacroExpander::lex(Token *token) { while (true) { @@ -97,7 +97,7 @@ void MacroExpander::lex(Token* token) } } -void MacroExpander::getToken(Token* token) +void MacroExpander::getToken(Token *token) { if (mReserveToken.get()) { @@ -122,11 +122,11 @@ void MacroExpander::getToken(Token* token) } } -void MacroExpander::ungetToken(const Token& token) +void MacroExpander::ungetToken(const Token &token) { if (!mContextStack.empty()) { - MacroContext* context = mContextStack.back(); + MacroContext *context = mContextStack.back(); context->unget(); assert(context->replacements[context->index] == token); } @@ -148,7 +148,7 @@ bool MacroExpander::isNextTokenLeftParen() return lparen; } -bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier) +bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier) { assert(!macro.disabled); assert(!identifier.expansionDisabled()); @@ -162,7 +162,7 @@ bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier) // Macro is disabled for expansion until it is popped off the stack. macro.disabled = true; - MacroContext* context = new MacroContext; + MacroContext *context = new MacroContext; context->macro = ¯o; context->replacements.swap(replacements); mContextStack.push_back(context); @@ -173,7 +173,7 @@ void MacroExpander::popMacro() { assert(!mContextStack.empty()); - MacroContext* context = mContextStack.back(); + MacroContext *context = mContextStack.back(); mContextStack.pop_back(); assert(context->empty()); @@ -182,9 +182,9 @@ void MacroExpander::popMacro() delete context; } -bool MacroExpander::expandMacro(const Macro& macro, - const Token& identifier, - std::vector<Token>* replacements) +bool MacroExpander::expandMacro(const Macro ¯o, + const Token &identifier, + std::vector<Token> *replacements) { replacements->clear(); if (macro.type == Macro::kTypeObj) @@ -239,9 +239,9 @@ bool MacroExpander::expandMacro(const Macro& macro, return true; } -bool MacroExpander::collectMacroArgs(const Macro& macro, - const Token& identifier, - std::vector<MacroArg>* args) +bool MacroExpander::collectMacroArgs(const Macro ¯o, + const Token &identifier, + std::vector<MacroArg> *args) { Token token; getToken(&token); @@ -276,7 +276,8 @@ bool MacroExpander::collectMacroArgs(const Macro& macro, // The individual arguments are separated by comma tokens, but // the comma tokens between matching inner parentheses do not // seperate arguments. - if (openParens == 1) args->push_back(MacroArg()); + if (openParens == 1) + args->push_back(MacroArg()); isArg = openParens != 1; break; default: @@ -285,14 +286,15 @@ bool MacroExpander::collectMacroArgs(const Macro& macro, } if (isArg) { - MacroArg& arg = args->back(); + MacroArg &arg = args->back(); // Initial whitespace is not part of the argument. - if (arg.empty()) token.setHasLeadingSpace(false); + if (arg.empty()) + token.setHasLeadingSpace(false); arg.push_back(token); } } - const Macro::Parameters& params = macro.parameters; + const Macro::Parameters ¶ms = macro.parameters; // If there is only one empty argument, it is equivalent to no argument. if (params.empty() && (args->size() == 1) && args->front().empty()) { @@ -313,7 +315,7 @@ bool MacroExpander::collectMacroArgs(const Macro& macro, // inserted into the macro body. for (std::size_t i = 0; i < args->size(); ++i) { - MacroArg& arg = args->at(i); + MacroArg &arg = args->at(i); TokenLexer lexer(&arg); MacroExpander expander(&lexer, mMacroSet, mDiagnostics); @@ -328,13 +330,13 @@ bool MacroExpander::collectMacroArgs(const Macro& macro, return true; } -void MacroExpander::replaceMacroParams(const Macro& macro, - const std::vector<MacroArg>& args, - std::vector<Token>* replacements) +void MacroExpander::replaceMacroParams(const Macro ¯o, + const std::vector<MacroArg> &args, + std::vector<Token> *replacements) { for (std::size_t i = 0; i < macro.replacements.size(); ++i) { - const Token& repl = macro.replacements[i]; + const Token &repl = macro.replacements[i]; if (repl.type != Token::IDENTIFIER) { replacements->push_back(repl); @@ -353,7 +355,7 @@ void MacroExpander::replaceMacroParams(const Macro& macro, } std::size_t iArg = std::distance(macro.parameters.begin(), iter); - const MacroArg& arg = args[iArg]; + const MacroArg &arg = args[iArg]; if (arg.empty()) { continue; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h index 21b67571f19..d4fd0917868 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h @@ -23,51 +23,65 @@ class Diagnostics; class MacroExpander : public Lexer { public: - MacroExpander(Lexer* lexer, MacroSet* macroSet, Diagnostics* diagnostics); + MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics); virtual ~MacroExpander(); - virtual void lex(Token* token); + virtual void lex(Token *token); private: PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander); - void getToken(Token* token); - void ungetToken(const Token& token); + void getToken(Token *token); + void ungetToken(const Token &token); bool isNextTokenLeftParen(); - bool pushMacro(const Macro& macro, const Token& identifier); + bool pushMacro(const Macro ¯o, const Token &identifier); void popMacro(); - bool expandMacro(const Macro& macro, - const Token& identifier, - std::vector<Token>* replacements); + bool expandMacro(const Macro ¯o, + const Token &identifier, + std::vector<Token> *replacements); typedef std::vector<Token> MacroArg; - bool collectMacroArgs(const Macro& macro, - const Token& identifier, - std::vector<MacroArg>* args); - void replaceMacroParams(const Macro& macro, - const std::vector<MacroArg>& args, - std::vector<Token>* replacements); + bool collectMacroArgs(const Macro ¯o, + const Token &identifier, + std::vector<MacroArg> *args); + void replaceMacroParams(const Macro ¯o, + const std::vector<MacroArg> &args, + std::vector<Token> *replacements); struct MacroContext { - const Macro* macro; + const Macro *macro; std::size_t index; std::vector<Token> replacements; - MacroContext() : macro(0), index(0) { } - bool empty() const { return index == replacements.size(); } - const Token& get() { return replacements[index++]; } - void unget() { assert(index > 0); --index; } + MacroContext() + : macro(0), + index(0) + { + } + bool empty() const + { + return index == replacements.size(); + } + const Token &get() + { + return replacements[index++]; + } + void unget() + { + assert(index > 0); + --index; + } }; - Lexer* mLexer; - MacroSet* mMacroSet; - Diagnostics* mDiagnostics; + Lexer *mLexer; + MacroSet *mMacroSet; + Diagnostics *mDiagnostics; std::auto_ptr<Token> mReserveToken; - std::vector<MacroContext*> mContextStack; + std::vector<MacroContext *> mContextStack; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp index 580ffba459f..3522fa1abb9 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp @@ -21,24 +21,24 @@ namespace pp struct PreprocessorImpl { - Diagnostics* diagnostics; + Diagnostics *diagnostics; MacroSet macroSet; Tokenizer tokenizer; DirectiveParser directiveParser; MacroExpander macroExpander; - PreprocessorImpl(Diagnostics* diag, - DirectiveHandler* directiveHandler) : - diagnostics(diag), - tokenizer(diag), - directiveParser(&tokenizer, ¯oSet, diag, directiveHandler), - macroExpander(&directiveParser, ¯oSet, diag) + PreprocessorImpl(Diagnostics *diag, + DirectiveHandler *directiveHandler) + : diagnostics(diag), + tokenizer(diag), + directiveParser(&tokenizer, ¯oSet, diag, directiveHandler), + macroExpander(&directiveParser, ¯oSet, diag) { } }; -Preprocessor::Preprocessor(Diagnostics* diagnostics, - DirectiveHandler* directiveHandler) +Preprocessor::Preprocessor(Diagnostics *diagnostics, + DirectiveHandler *directiveHandler) { mImpl = new PreprocessorImpl(diagnostics, directiveHandler); } @@ -49,7 +49,7 @@ Preprocessor::~Preprocessor() } bool Preprocessor::init(size_t count, - const char* const string[], + const char * const string[], const int length[]) { static const int kGLSLVersion = 100; @@ -63,7 +63,7 @@ bool Preprocessor::init(size_t count, return mImpl->tokenizer.init(count, string, length); } -void Preprocessor::predefineMacro(const char* name, int value) +void Preprocessor::predefineMacro(const char *name, int value) { std::ostringstream stream; stream << value; @@ -81,12 +81,7 @@ void Preprocessor::predefineMacro(const char* name, int value) mImpl->macroSet[name] = macro; } -void Preprocessor::setMaxTokenLength(size_t maxLength) -{ - mImpl->tokenizer.setMaxTokenLength(maxLength); -} - -void Preprocessor::lex(Token* token) +void Preprocessor::lex(Token *token) { bool validToken = false; while (!validToken) @@ -115,5 +110,9 @@ void Preprocessor::lex(Token* token) } } -} // namespace pp +void Preprocessor::setMaxTokenSize(size_t maxTokenSize) +{ + mImpl->tokenizer.setMaxTokenSize(maxTokenSize); +} +} // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h index 9a90d79a1a1..0a55f1c9c16 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h @@ -22,7 +22,7 @@ struct Token; class Preprocessor { public: - Preprocessor(Diagnostics* diagnostics, DirectiveHandler* directiveHandler); + Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler); ~Preprocessor(); // count: specifies the number of elements in the string and length arrays. @@ -34,22 +34,19 @@ class Preprocessor // Each element in the length array may contain the length of the // corresponding string or a value less than 0 to indicate that the string // is null terminated. - bool init(size_t count, const char* const string[], const int length[]); + bool init(size_t count, const char * const string[], const int length[]); // Adds a pre-defined macro. - void predefineMacro(const char* name, int value); - // Sets maximum allowed token length. - // If token length exceeds this limit, - // the token text will be truncated to the given maximum length, and - // TOKEN_TOO_LONG diagnostic will be generated. - // The maximum length defaults to 256. - void setMaxTokenLength(size_t maxLength); + void predefineMacro(const char *name, int value); - void lex(Token* token); + void lex(Token *token); + + // Set maximum preprocessor token size + void setMaxTokenSize(size_t maxTokenSize); private: PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor); - PreprocessorImpl* mImpl; + PreprocessorImpl *mImpl; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/SourceLocation.h b/chromium/third_party/angle/src/compiler/preprocessor/SourceLocation.h index 6982613ac74..d4c1a5e1788 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/SourceLocation.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/SourceLocation.h @@ -12,10 +12,18 @@ namespace pp struct SourceLocation { - SourceLocation() : file(0), line(0) { } - SourceLocation(int f, int l) : file(f), line(l) { } + SourceLocation() + : file(0), + line(0) + { + } + SourceLocation(int f, int l) + : file(f), + line(l) + { + } - bool equals(const SourceLocation& other) const + bool equals(const SourceLocation &other) const { return (file == other.file) && (line == other.line); } @@ -24,12 +32,12 @@ struct SourceLocation int line; }; -inline bool operator==(const SourceLocation& lhs, const SourceLocation& rhs) +inline bool operator==(const SourceLocation &lhs, const SourceLocation &rhs) { return lhs.equals(rhs); } -inline bool operator!=(const SourceLocation& lhs, const SourceLocation& rhs) +inline bool operator!=(const SourceLocation &lhs, const SourceLocation &rhs) { return !lhs.equals(rhs); } diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp index 67f50aa32ce..d102654747d 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp @@ -21,7 +21,7 @@ void Token::reset() text.clear(); } -bool Token::equals(const Token& other) const +bool Token::equals(const Token &other) const { return (type == other.type) && (flags == other.flags) && @@ -53,25 +53,25 @@ void Token::setExpansionDisabled(bool disable) flags &= ~EXPANSION_DISABLED; } -bool Token::iValue(int* value) const +bool Token::iValue(int *value) const { assert(type == CONST_INT); return numeric_lex_int(text, value); } -bool Token::uValue(unsigned int* value) const +bool Token::uValue(unsigned int *value) const { assert(type == CONST_INT); return numeric_lex_int(text, value); } -bool Token::fValue(float* value) const +bool Token::fValue(float *value) const { assert(type == CONST_FLOAT); return numeric_lex_float(text, value); } -std::ostream& operator<<(std::ostream& out, const Token& token) +std::ostream &operator<<(std::ostream &out, const Token &token) { if (token.hasLeadingSpace()) out << " "; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Token.h b/chromium/third_party/angle/src/compiler/preprocessor/Token.h index 8b553aecb68..8832e279c74 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Token.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Token.h @@ -62,27 +62,40 @@ struct Token EXPANSION_DISABLED = 1 << 2 }; - Token() : type(0), flags(0) { } + Token() + : type(0), + flags(0) + { + } void reset(); - bool equals(const Token& other) const; + bool equals(const Token &other) const; // Returns true if this is the first token on line. // It disregards any leading whitespace. - bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; } + bool atStartOfLine() const + { + return (flags & AT_START_OF_LINE) != 0; + } void setAtStartOfLine(bool start); - bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; } + bool hasLeadingSpace() const + { + return (flags & HAS_LEADING_SPACE) != 0; + } void setHasLeadingSpace(bool space); - bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; } + bool expansionDisabled() const + { + return (flags & EXPANSION_DISABLED) != 0; + } void setExpansionDisabled(bool disable); // Converts text into numeric value for CONST_INT and CONST_FLOAT token. // Returns false if the parsed value cannot fit into an int or float. - bool iValue(int* value) const; - bool uValue(unsigned int* value) const; - bool fValue(float* value) const; + bool iValue(int *value) const; + bool uValue(unsigned int *value) const; + bool fValue(float *value) const; int type; unsigned int flags; @@ -90,17 +103,17 @@ struct Token std::string text; }; -inline bool operator==(const Token& lhs, const Token& rhs) +inline bool operator==(const Token &lhs, const Token &rhs) { return lhs.equals(rhs); } -inline bool operator!=(const Token& lhs, const Token& rhs) +inline bool operator!=(const Token &lhs, const Token &rhs) { return !lhs.equals(rhs); } -extern std::ostream& operator<<(std::ostream& out, const Token& token); +extern std::ostream &operator<<(std::ostream &out, const Token &token); } // namepsace pp #endif // COMPILER_PREPROCESSOR_TOKEN_H_ diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp index 21f11041d06..04ed9fc7e01 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp @@ -1,6 +1,6 @@ #line 16 "./Tokenizer.l" // -// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2011-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -18,7 +18,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -64,7 +64,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -95,6 +94,8 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif +#endif /* ! C99 */ + #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -185,6 +186,11 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; typedef size_t yy_size_t; #endif +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 @@ -335,7 +341,7 @@ void ppfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define ppwrap(n) 1 +#define ppwrap(yyscanner) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -368,17 +374,19 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[87] = +static yyconst flex_int16_t yy_accept[98] = { 0, 0, 0, 0, 0, 39, 37, 34, 35, 35, 33, 7, 33, 33, 33, 33, 33, 33, 33, 33, 9, 9, 33, 33, 33, 8, 37, 33, 33, 3, 5, 5, 4, 34, 35, 19, 27, 20, 30, 25, 12, 23, 13, 24, 10, 2, 1, 26, 10, 9, 11, - 11, 11, 11, 9, 14, 16, 18, 17, 15, 8, - 36, 36, 31, 21, 32, 22, 3, 5, 6, 11, - 10, 11, 1, 10, 11, 0, 10, 9, 28, 29, - 0, 10, 10, 10, 10, 0 + 11, 11, 9, 11, 9, 9, 14, 16, 18, 17, + 15, 8, 36, 36, 31, 21, 32, 22, 3, 5, + 6, 11, 10, 11, 10, 1, 10, 11, 10, 0, + 10, 9, 9, 9, 28, 29, 0, 10, 10, 10, + 10, 9, 10, 10, 9, 10, 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -389,14 +397,14 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, 9, 10, 11, 9, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17, 9, 9, 18, - 19, 20, 9, 1, 21, 21, 21, 21, 22, 21, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, - 9, 25, 9, 26, 23, 1, 21, 21, 21, 21, - - 22, 21, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, - 23, 23, 9, 27, 9, 9, 1, 1, 1, 1, + 19, 20, 9, 1, 21, 21, 21, 21, 22, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 24, 24, 26, 24, 24, + 9, 27, 9, 28, 24, 1, 21, 21, 21, 21, + + 22, 23, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 25, 24, 24, 26, + 24, 24, 9, 29, 9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -413,89 +421,101 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[28] = +static yyconst flex_int32_t yy_meta[30] = { 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 3, 1, 1, 4, 1, 5, 5, 5, 1, 1, 1, - 5, 5, 5, 5, 1, 1, 1 + 5, 5, 5, 5, 5, 5, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[92] = +static yyconst flex_int16_t yy_base[103] = { 0, - 0, 0, 25, 27, 162, 163, 159, 163, 152, 132, - 163, 131, 24, 163, 116, 22, 26, 31, 30, 37, - 40, 44, 115, 46, 0, 64, 50, 15, 0, 163, - 124, 91, 88, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 163, 64, 163, 0, 163, 76, 54, 58, - 79, 91, 91, 0, 56, 163, 163, 163, 32, 0, - 163, 36, 163, 163, 163, 163, 0, 163, 163, 94, - 0, 106, 0, 0, 113, 55, 72, 113, 163, 163, - 116, 101, 108, 123, 126, 163, 143, 31, 148, 153, - 155 - + 0, 0, 27, 29, 137, 194, 133, 194, 117, 100, + 194, 98, 26, 194, 94, 24, 28, 33, 32, 39, + 51, 39, 80, 50, 0, 68, 25, 54, 0, 194, + 88, 71, 80, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 71, 194, 0, 194, 85, 55, 64, + 99, 111, 53, 105, 0, 50, 55, 194, 194, 194, + 40, 0, 194, 38, 194, 194, 194, 194, 0, 194, + 194, 117, 0, 130, 0, 0, 0, 137, 0, 88, + 113, 0, 131, 0, 194, 194, 143, 139, 152, 150, + 0, 13, 153, 194, 0, 194, 194, 176, 31, 181, + + 186, 188 } ; -static yyconst flex_int16_t yy_def[92] = +static yyconst flex_int16_t yy_def[103] = { 0, - 86, 1, 87, 87, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 20, 86, 86, 86, 88, 86, 86, 86, 89, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 90, 86, 86, 20, 20, - 48, 51, 91, 21, 86, 86, 86, 86, 86, 88, - 86, 86, 86, 86, 86, 86, 89, 86, 86, 44, - 44, 70, 90, 48, 51, 86, 52, 91, 86, 86, - 86, 72, 75, 86, 86, 0, 86, 86, 86, 86, - 86 - + 97, 1, 98, 98, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 20, 97, 97, 97, 99, 97, 97, 97, 100, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 101, 97, 97, 20, 20, + 50, 51, 51, 102, 21, 51, 97, 97, 97, 97, + 97, 99, 97, 97, 97, 97, 97, 97, 100, 97, + 97, 44, 44, 72, 72, 101, 48, 51, 51, 97, + 52, 51, 102, 51, 97, 97, 97, 74, 78, 97, + 51, 51, 97, 97, 51, 97, 0, 97, 97, 97, + + 97, 97 } ; -static yyconst flex_int16_t yy_nxt[191] = +static yyconst flex_int16_t yy_nxt[224] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, - 25, 25, 25, 25, 26, 27, 28, 30, 31, 30, - 31, 37, 40, 65, 32, 60, 32, 42, 61, 45, - 41, 66, 38, 46, 43, 44, 44, 44, 47, 48, - 80, 49, 49, 50, 54, 54, 54, 51, 52, 51, - 53, 55, 56, 51, 58, 59, 61, 62, 63, 84, - 84, 84, 50, 50, 79, 64, 70, 51, 71, 71, - 71, 51, 86, 86, 70, 72, 70, 70, 51, 33, - 74, 74, 74, 51, 51, 51, 51, 75, 51, 51, - - 51, 76, 76, 51, 69, 77, 77, 77, 70, 70, - 70, 86, 86, 51, 51, 70, 81, 81, 86, 86, - 82, 82, 82, 81, 81, 51, 68, 83, 83, 83, - 85, 85, 85, 57, 39, 51, 51, 84, 84, 84, - 85, 85, 85, 29, 29, 29, 29, 29, 67, 36, - 35, 67, 67, 73, 34, 73, 73, 73, 78, 78, - 33, 86, 5, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86 + 25, 25, 25, 25, 25, 25, 26, 27, 28, 30, + 31, 30, 31, 37, 40, 62, 32, 95, 32, 42, + 63, 45, 41, 65, 38, 46, 43, 44, 44, 44, + 47, 48, 66, 49, 49, 50, 57, 58, 86, 51, + 52, 51, 51, 53, 54, 55, 55, 55, 60, 61, + 63, 64, 67, 85, 84, 56, 51, 82, 50, 50, + 51, 33, 68, 72, 71, 73, 73, 73, 51, 51, + 70, 72, 74, 75, 72, 72, 72, 51, 59, 77, + + 77, 77, 90, 90, 90, 51, 78, 79, 51, 51, + 51, 51, 39, 51, 51, 51, 36, 51, 35, 34, + 51, 80, 80, 97, 97, 81, 81, 81, 51, 51, + 51, 72, 72, 72, 33, 91, 97, 97, 72, 72, + 87, 87, 97, 51, 88, 88, 88, 87, 87, 97, + 97, 89, 89, 89, 51, 92, 51, 93, 93, 93, + 97, 75, 97, 97, 90, 90, 90, 93, 93, 93, + 97, 97, 94, 97, 79, 96, 29, 29, 29, 29, + 29, 69, 97, 97, 69, 69, 76, 97, 76, 76, + 76, 83, 83, 5, 97, 97, 97, 97, 97, 97, + + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97 } ; -static yyconst flex_int16_t yy_chk[191] = +static yyconst flex_int16_t yy_chk[224] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, - 4, 13, 16, 28, 3, 88, 4, 17, 62, 19, - 16, 28, 13, 19, 17, 18, 18, 18, 19, 20, - 59, 20, 20, 20, 21, 21, 21, 20, 20, 20, - 20, 22, 22, 21, 24, 24, 26, 26, 27, 76, - 76, 76, 50, 50, 55, 27, 44, 49, 44, 44, - 44, 50, 77, 77, 44, 44, 44, 44, 48, 33, - 48, 48, 48, 51, 51, 51, 48, 48, 48, 48, - - 51, 52, 52, 53, 32, 52, 52, 52, 70, 70, - 70, 82, 82, 53, 53, 70, 72, 72, 83, 83, - 72, 72, 72, 75, 75, 78, 31, 75, 75, 75, - 81, 81, 81, 23, 15, 78, 78, 84, 84, 84, - 85, 85, 85, 87, 87, 87, 87, 87, 89, 12, - 10, 89, 89, 90, 9, 90, 90, 90, 91, 91, - 7, 5, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 4, 4, 13, 16, 99, 3, 92, 4, 17, + 64, 19, 16, 27, 13, 19, 17, 18, 18, 18, + 19, 20, 27, 20, 20, 20, 22, 22, 61, 20, + 20, 20, 20, 20, 20, 21, 21, 21, 24, 24, + 26, 26, 28, 57, 56, 21, 21, 53, 50, 50, + 49, 33, 28, 44, 32, 44, 44, 44, 50, 50, + 31, 44, 44, 44, 44, 44, 44, 48, 23, 48, + + 48, 48, 80, 80, 80, 48, 48, 48, 48, 48, + 48, 51, 15, 51, 51, 51, 12, 54, 10, 9, + 51, 52, 52, 81, 81, 52, 52, 52, 54, 54, + 54, 72, 72, 72, 7, 81, 5, 0, 72, 72, + 74, 74, 0, 83, 74, 74, 74, 78, 78, 88, + 88, 78, 78, 78, 83, 83, 83, 87, 87, 87, + 0, 88, 89, 89, 90, 90, 90, 93, 93, 93, + 0, 0, 90, 0, 89, 93, 98, 98, 98, 98, + 98, 100, 0, 0, 100, 100, 101, 0, 101, 101, + 101, 102, 102, 97, 97, 97, 97, 97, 97, 97, + + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97 } ; /* The intent behind this definition is that it'll catch @@ -507,7 +527,7 @@ static yyconst flex_int16_t yy_chk[191] = #define YY_RESTORE_YY_MORE_OFFSET /* // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -646,6 +666,10 @@ int ppget_lineno (yyscan_t yyscanner ); void ppset_lineno (int line_number ,yyscan_t yyscanner ); +int ppget_column (yyscan_t yyscanner ); + +void ppset_column (int column_no ,yyscan_t yyscanner ); + YYSTYPE * ppget_lval (yyscan_t yyscanner ); void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -694,7 +718,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -705,7 +729,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - yy_size_t n; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -847,13 +871,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 87 ) + if ( yy_current_state >= 98 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 86 ); + while ( yy_current_state != 97 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1346,7 +1370,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); @@ -1446,7 +1470,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 87 ) + if ( yy_current_state >= 98 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1475,12 +1499,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 87 ) + if ( yy_current_state >= 98 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 86); + yy_is_jam = (yy_current_state == 97); + (void)yyg; return yy_is_jam ? 0 : yy_current_state; } @@ -1882,8 +1907,8 @@ YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) /** Setup the input buffer state to scan the given bytes. The next call to pplex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ @@ -1891,7 +1916,8 @@ YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len { YY_BUFFER_STATE b; char *buf; - yy_size_t n, i; + yy_size_t n; + yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2037,7 +2063,7 @@ void ppset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ppset_lineno called with no buffer" , yyscanner); + YY_FATAL_ERROR( "ppset_lineno called with no buffer" ); yylineno = line_number; } @@ -2052,7 +2078,7 @@ void ppset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ppset_column called with no buffer" , yyscanner); + YY_FATAL_ERROR( "ppset_column called with no buffer" ); yycolumn = column_no; } @@ -2290,9 +2316,9 @@ void ppfree (void * ptr , yyscan_t yyscanner) namespace pp { -Tokenizer::Tokenizer(Diagnostics* diagnostics) +Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(0), - mMaxTokenLength(256) + mMaxTokenSize(256) { mContext.diagnostics = diagnostics; } @@ -2302,9 +2328,10 @@ Tokenizer::~Tokenizer() destroyScanner(); } -bool Tokenizer::init(size_t count, const char* const string[], const int length[]) +bool Tokenizer::init(size_t count, const char * const string[], const int length[]) { - if ((count > 0) && (string == 0)) return false; + if ((count > 0) && (string == 0)) + return false; mContext.input = Input(count, string, length); return initScanner(); @@ -2322,14 +2349,19 @@ void Tokenizer::setLineNumber(int line) ppset_lineno(line,mHandle); } -void Tokenizer::lex(Token* token) +void Tokenizer::setMaxTokenSize(size_t maxTokenSize) +{ + mMaxTokenSize = maxTokenSize; +} + +void Tokenizer::lex(Token *token) { token->type = pplex(&token->text,&token->location,mHandle); - if (token->text.size() > mMaxTokenLength) + if (token->text.size() > mMaxTokenSize) { mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG, token->location, token->text); - token->text.erase(mMaxTokenLength); + token->text.erase(mMaxTokenSize); } token->flags = 0; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h index 9d131f865a2..07ad93da052 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -21,7 +21,7 @@ class Tokenizer : public Lexer public: struct Context { - Diagnostics* diagnostics; + Diagnostics *diagnostics; Input input; // The location where yytext points to. Token location should track @@ -33,25 +33,25 @@ class Tokenizer : public Lexer bool lineStart; }; - Tokenizer(Diagnostics* diagnostics); + Tokenizer(Diagnostics *diagnostics); ~Tokenizer(); - bool init(size_t count, const char* const string[], const int length[]); + bool init(size_t count, const char * const string[], const int length[]); - void setMaxTokenLength(size_t maxLength) { mMaxTokenLength = maxLength; } void setFileNumber(int file); void setLineNumber(int line); + void setMaxTokenSize(size_t maxTokenSize); - virtual void lex(Token* token); + virtual void lex(Token *token); private: PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer); bool initScanner(); void destroyScanner(); - void* mHandle; // Scanner handle. + void *mHandle; // Scanner handle. Context mContext; // Scanner extra. - size_t mMaxTokenLength; + size_t mMaxTokenSize; // Maximum token size }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l index 01f0177b6c2..2a77b905a4c 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l +++ b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l @@ -1,6 +1,6 @@ /* // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -14,7 +14,7 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. %top{ // -// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2011-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -78,9 +78,9 @@ NEWLINE \n|\r|\r\n IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] -DECIMAL_CONSTANT [1-9][0-9]* -OCTAL_CONSTANT 0[0-7]* -HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+ +DECIMAL_CONSTANT [1-9][0-9]*[uU]? +OCTAL_CONSTANT 0[0-7]*[uU]? +HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+[uU]? DIGIT [0-9] EXPONENT_PART [eE][+-]?{DIGIT}+ @@ -114,12 +114,12 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") return pp::Token::IDENTIFIER; } -{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { +({DECIMAL_CONSTANT}[uU]?)|({OCTAL_CONSTANT}[uU]?)|({HEXADECIMAL_CONSTANT}[uU]?) { yylval->assign(yytext, yyleng); return pp::Token::CONST_INT; } -({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { +({DIGIT}+{EXPONENT_PART}[fF]?)|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?[fF]?) { yylval->assign(yytext, yyleng); return pp::Token::CONST_FLOAT; } @@ -256,7 +256,7 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") if (YY_START == COMMENT) { - yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, + yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT, pp::SourceLocation(yyfileno, yylineno), ""); } @@ -267,9 +267,7 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") namespace pp { -Tokenizer::Tokenizer(Diagnostics* diagnostics) - : mHandle(0), - mMaxTokenLength(256) +Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(0) { mContext.diagnostics = diagnostics; } @@ -279,9 +277,10 @@ Tokenizer::~Tokenizer() destroyScanner(); } -bool Tokenizer::init(size_t count, const char* const string[], const int length[]) +bool Tokenizer::init(size_t count, const char * const string[], const int length[]) { - if ((count > 0) && (string == 0)) return false; + if ((count > 0) && (string == 0)) + return false; mContext.input = Input(count, string, length); return initScanner(); @@ -299,14 +298,19 @@ void Tokenizer::setLineNumber(int line) yyset_lineno(line, mHandle); } -void Tokenizer::lex(Token* token) +void Tokenizer::setMaxTokenSize(size_t maxTokenSize) +{ + mMaxTokenSize = maxTokenSize; +} + +void Tokenizer::lex(Token *token) { token->type = yylex(&token->text, &token->location, mHandle); - if (token->text.size() > mMaxTokenLength) + if (token->text.size() > mMaxTokenSize) { - mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG, + mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG, token->location, token->text); - token->text.erase(mMaxTokenLength); + token->text.erase(mMaxTokenSize); } token->flags = 0; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/numeric_lex.h b/chromium/third_party/angle/src/compiler/preprocessor/numeric_lex.h index b04125d2309..8a24540696e 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/numeric_lex.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/numeric_lex.h @@ -13,7 +13,7 @@ namespace pp { -inline std::ios::fmtflags numeric_base_int(const std::string& str) +inline std::ios::fmtflags numeric_base_int(const std::string &str) { if ((str.size() >= 2) && (str[0] == '0') && @@ -21,7 +21,7 @@ inline std::ios::fmtflags numeric_base_int(const std::string& str) { return std::ios::hex; } - else if ((str.size() >= 1) && (str[0] == '0')) + if ((str.size() >= 1) && (str[0] == '0')) { return std::ios::oct; } @@ -34,7 +34,7 @@ inline std::ios::fmtflags numeric_base_int(const std::string& str) // in which case false is returned. template<typename IntType> -bool numeric_lex_int(const std::string& str, IntType* value) +bool numeric_lex_int(const std::string &str, IntType *value) { std::istringstream stream(str); // This should not be necessary, but MSVS has a buggy implementation. @@ -46,7 +46,7 @@ bool numeric_lex_int(const std::string& str, IntType* value) } template<typename FloatType> -bool numeric_lex_float(const std::string& str, FloatType* value) +bool numeric_lex_float(const std::string &str, FloatType *value) { std::istringstream stream(str); // Force "C" locale so that decimal character is always '.', and diff --git a/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h b/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h index 17164ea8b03..9fba9385c5e 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h @@ -12,7 +12,7 @@ // A macro to disallow the copy constructor and operator= functions // This must be used in the private: declarations for a class. #define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) + TypeName(const TypeName &); \ + void operator=(const TypeName &) #endif // COMPILER_PREPROCESSOR_PPUTILS_H_ diff --git a/chromium/third_party/angle/src/compiler/preprocessor/preprocessor.vcxproj b/chromium/third_party/angle/src/compiler/preprocessor/preprocessor.vcxproj deleted file mode 100644 index 14f701b01ef..00000000000 --- a/chromium/third_party/angle/src/compiler/preprocessor/preprocessor.vcxproj +++ /dev/null @@ -1,172 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}</ProjectGuid> - <RootNamespace>preprocessor</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="DiagnosticsBase.cpp" /> - <ClCompile Include="DirectiveHandlerBase.cpp" /> - <ClCompile Include="DirectiveParser.cpp" /> - <ClCompile Include="ExpressionParser.cpp" /> - <ClCompile Include="Input.cpp" /> - <ClCompile Include="Lexer.cpp" /> - <ClCompile Include="Macro.cpp" /> - <ClCompile Include="MacroExpander.cpp" /> - <ClCompile Include="Preprocessor.cpp" /> - <ClCompile Include="Token.cpp" /> - <ClCompile Include="Tokenizer.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="length_limits.h" /> - <ClInclude Include="DiagnosticsBase.h" /> - <ClInclude Include="DirectiveHandlerBase.h" /> - <ClInclude Include="DirectiveParser.h" /> - <ClInclude Include="ExpressionParser.h" /> - <ClInclude Include="Input.h" /> - <ClInclude Include="Lexer.h" /> - <ClInclude Include="Macro.h" /> - <ClInclude Include="MacroExpander.h" /> - <ClInclude Include="numeric_lex.h" /> - <ClInclude Include="pp_utils.h" /> - <ClInclude Include="Preprocessor.h" /> - <ClInclude Include="SourceLocation.h" /> - <ClInclude Include="Token.h" /> - <ClInclude Include="Tokenizer.h" /> - </ItemGroup> - <ItemGroup> - <None Include="Tokenizer.l" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/preprocessor/preprocessor.vcxproj.filters b/chromium/third_party/angle/src/compiler/preprocessor/preprocessor.vcxproj.filters deleted file mode 100644 index 8c8da8687ab..00000000000 --- a/chromium/third_party/angle/src/compiler/preprocessor/preprocessor.vcxproj.filters +++ /dev/null @@ -1,100 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="DirectiveParser.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ExpressionParser.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Input.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Lexer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Macro.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="MacroExpander.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Preprocessor.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Token.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Tokenizer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="DiagnosticsBase.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="DirectiveHandlerBase.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="DirectiveParser.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ExpressionParser.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Input.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Lexer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Macro.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="MacroExpander.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="numeric_lex.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="pp_utils.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Preprocessor.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="SourceLocation.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Token.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Tokenizer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="length_limits.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="DiagnosticsBase.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="DirectiveHandlerBase.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <None Include="Tokenizer.l"> - <Filter>Source Files</Filter> - </None> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator.vcxproj b/chromium/third_party/angle/src/compiler/translator.vcxproj deleted file mode 100644 index 54d71a1d61a..00000000000 --- a/chromium/third_party/angle/src/compiler/translator.vcxproj +++ /dev/null @@ -1,304 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}</ProjectGuid> - <RootNamespace>compiler</RootNamespace> - <Keyword>Win32Proj</Keyword> - <ProjectName>translator</ProjectName> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\common\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\common\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)../;$(ProjectDir)../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)../;$(ProjectDir)../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4267;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> - <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)../;$(ProjectDir)../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> - <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)../;$(ProjectDir)../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4267;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="BuiltInFunctionEmulator.cpp" /> - <ClCompile Include="CodeGen.cpp" /> - <ClCompile Include="Compiler.cpp" /> - <ClCompile Include="debug.cpp" /> - <ClCompile Include="DetectCallDepth.cpp" /> - <ClCompile Include="DetectDiscontinuity.cpp" /> - <ClCompile Include="Diagnostics.cpp" /> - <ClCompile Include="DirectiveHandler.cpp" /> - <ClCompile Include="ForLoopUnroll.cpp" /> - <ClCompile Include="InfoSink.cpp" /> - <ClCompile Include="Initialize.cpp" /> - <ClCompile Include="InitializeDll.cpp" /> - <ClCompile Include="InitializeGLPosition.cpp" /> - <ClCompile Include="InitializeParseContext.cpp" /> - <ClCompile Include="Intermediate.cpp" /> - <ClCompile Include="intermOut.cpp" /> - <ClCompile Include="IntermTraverse.cpp" /> - <ClCompile Include="MapLongVariableNames.cpp" /> - <ClCompile Include="ossource_win.cpp" /> - <ClCompile Include="OutputESSL.cpp" /> - <ClCompile Include="OutputGLSL.cpp" /> - <ClCompile Include="OutputGLSLBase.cpp" /> - <ClCompile Include="OutputHLSL.cpp" /> - <ClCompile Include="parseConst.cpp" /> - <ClCompile Include="ParseContext.cpp" /> - <ClCompile Include="PoolAlloc.cpp" /> - <ClCompile Include="QualifierAlive.cpp" /> - <ClCompile Include="RemoveTree.cpp" /> - <ClCompile Include="SearchSymbol.cpp" /> - <ClCompile Include="ShaderLang.cpp" /> - <ClCompile Include="SymbolTable.cpp" /> - <ClCompile Include="TranslatorESSL.cpp" /> - <ClCompile Include="TranslatorGLSL.cpp" /> - <ClCompile Include="TranslatorHLSL.cpp" /> - <ClCompile Include="UnfoldShortCircuit.cpp" /> - <ClCompile Include="UnfoldShortCircuitAST.cpp" /> - <ClCompile Include="Uniform.cpp" /> - <ClCompile Include="util.cpp" /> - <ClCompile Include="ValidateLimitations.cpp" /> - <ClCompile Include="VariableInfo.cpp" /> - <ClCompile Include="VariablePacker.cpp" /> - <ClCompile Include="glslang_lex.cpp" /> - <ClCompile Include="glslang_tab.cpp" /> - <ClCompile Include="depgraph\DependencyGraph.cpp" /> - <ClCompile Include="depgraph\DependencyGraphBuilder.cpp" /> - <ClCompile Include="depgraph\DependencyGraphOutput.cpp" /> - <ClCompile Include="depgraph\DependencyGraphTraverse.cpp" /> - <ClCompile Include="timing\RestrictFragmentShaderTiming.cpp" /> - <ClCompile Include="timing\RestrictVertexShaderTiming.cpp" /> - <ClCompile Include="..\third_party\compiler\ArrayBoundsClamper.cpp" /> - <ClCompile Include="VersionGLSL.cpp" /> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="glslang.l"> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </Command> - <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalInputs)</AdditionalInputs> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </Command> - <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalInputs)</AdditionalInputs> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </Command> - <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalInputs)</AdditionalInputs> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </Command> - <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalInputs)</AdditionalInputs> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Outputs)</Outputs> - </CustomBuild> - <CustomBuild Include="glslang.y"> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - </Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - </Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - </Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - </Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Outputs)</Outputs> - </CustomBuild> - </ItemGroup> - <ItemGroup> - <ClInclude Include="BaseTypes.h" /> - <ClInclude Include="BuiltInFunctionEmulator.h" /> - <ClInclude Include="Common.h" /> - <ClInclude Include="ConstantUnion.h" /> - <ClInclude Include="debug.h" /> - <ClInclude Include="DetectCallDepth.h" /> - <ClInclude Include="DetectDiscontinuity.h" /> - <ClInclude Include="Diagnostics.h" /> - <ClInclude Include="DirectiveHandler.h" /> - <ClInclude Include="ForLoopUnroll.h" /> - <ClInclude Include="HashNames.h" /> - <ClInclude Include="InfoSink.h" /> - <ClInclude Include="Initialize.h" /> - <ClInclude Include="InitializeDll.h" /> - <ClInclude Include="InitializeGlobals.h" /> - <ClInclude Include="InitializeGLPosition.h" /> - <ClInclude Include="InitializeParseContext.h" /> - <ClInclude Include="intermediate.h" /> - <ClInclude Include="localintermediate.h" /> - <ClInclude Include="MapLongVariableNames.h" /> - <ClInclude Include="MMap.h" /> - <ClInclude Include="NodeSearch.h" /> - <ClInclude Include="osinclude.h" /> - <ClInclude Include="OutputESSL.h" /> - <ClInclude Include="OutputGLSL.h" /> - <ClInclude Include="OutputGLSLBase.h" /> - <ClInclude Include="OutputHLSL.h" /> - <ClInclude Include="ParseContext.h" /> - <ClInclude Include="PoolAlloc.h" /> - <ClInclude Include="QualifierAlive.h" /> - <ClInclude Include="RemoveTree.h" /> - <ClInclude Include="RenameFunction.h" /> - <ClInclude Include="..\..\include\GLSLANG\ShaderLang.h" /> - <ClInclude Include="SearchSymbol.h" /> - <ClInclude Include="ShHandle.h" /> - <ClInclude Include="SymbolTable.h" /> - <ClInclude Include="TranslatorESSL.h" /> - <ClInclude Include="TranslatorGLSL.h" /> - <ClInclude Include="TranslatorHLSL.h" /> - <ClInclude Include="Types.h" /> - <ClInclude Include="UnfoldShortCircuit.h" /> - <ClInclude Include="UnfoldShortCircuitAST.h" /> - <ClInclude Include="Uniform.h" /> - <ClInclude Include="util.h" /> - <ClInclude Include="ValidateLimitations.h" /> - <ClInclude Include="VariableInfo.h" /> - <ClInclude Include="VariablePacker.h" /> - <ClInclude Include="glslang_tab.h" /> - <ClInclude Include="timing\RestrictFragmentShaderTiming.h" /> - <ClInclude Include="timing\RestrictVertexShaderTiming.h" /> - <ClInclude Include="depgraph\DependencyGraph.h" /> - <ClInclude Include="depgraph\DependencyGraphBuilder.h" /> - <ClInclude Include="depgraph\DependencyGraphOutput.h" /> - <ClInclude Include="..\third_party\compiler\ArrayBoundsClamper.h" /> - <ClInclude Include="VersionGLSL.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator.vcxproj.filters b/chromium/third_party/angle/src/compiler/translator.vcxproj.filters deleted file mode 100644 index 1df6c7c28ac..00000000000 --- a/chromium/third_party/angle/src/compiler/translator.vcxproj.filters +++ /dev/null @@ -1,361 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Source Files\generated"> - <UniqueIdentifier>{eb8da157-b29c-43c3-880d-54679e176dc5}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\depgraph"> - <UniqueIdentifier>{b5410d3a-c3c8-4ae6-843a-b000d652632e}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\timing"> - <UniqueIdentifier>{a9847611-dcd5-4c89-8262-a22b96c7c98d}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Header Files\generated"> - <UniqueIdentifier>{094f7115-35d3-4c63-870c-ab5f393dc2c2}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\timing"> - <UniqueIdentifier>{5f5742e9-15e1-43b4-b1e7-0c118be14e04}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\depgraph"> - <UniqueIdentifier>{c4007e35-3c11-44d6-95f7-bb81db528068}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="BuiltInFunctionEmulator.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Compiler.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="debug.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="DetectCallDepth.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Diagnostics.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="DirectiveHandler.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ForLoopUnroll.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="InfoSink.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Initialize.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="InitializeDll.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="InitializeParseContext.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Intermediate.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="intermOut.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="IntermTraverse.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="MapLongVariableNames.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ossource_win.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="parseConst.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="PoolAlloc.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="QualifierAlive.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="RemoveTree.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ShaderLang.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="SymbolTable.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="util.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ValidateLimitations.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="VariableInfo.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="VariablePacker.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="glslang_lex.cpp"> - <Filter>Source Files\generated</Filter> - </ClCompile> - <ClCompile Include="glslang_tab.cpp"> - <Filter>Source Files\generated</Filter> - </ClCompile> - <ClCompile Include="depgraph\DependencyGraph.cpp"> - <Filter>Source Files\depgraph</Filter> - </ClCompile> - <ClCompile Include="depgraph\DependencyGraphBuilder.cpp"> - <Filter>Source Files\depgraph</Filter> - </ClCompile> - <ClCompile Include="depgraph\DependencyGraphOutput.cpp"> - <Filter>Source Files\depgraph</Filter> - </ClCompile> - <ClCompile Include="depgraph\DependencyGraphTraverse.cpp"> - <Filter>Source Files\depgraph</Filter> - </ClCompile> - <ClCompile Include="timing\RestrictFragmentShaderTiming.cpp"> - <Filter>Source Files\timing</Filter> - </ClCompile> - <ClCompile Include="timing\RestrictVertexShaderTiming.cpp"> - <Filter>Source Files\timing</Filter> - </ClCompile> - <ClCompile Include="..\third_party\compiler\ArrayBoundsClamper.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="InitializeGLPosition.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="DetectDiscontinuity.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="OutputHLSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="SearchSymbol.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="TranslatorHLSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="UnfoldShortCircuit.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Uniform.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="CodeGen.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="TranslatorGLSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="TranslatorESSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="OutputESSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="OutputGLSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="OutputGLSLBase.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="VersionGLSL.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="UnfoldShortCircuitAST.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ParseContext.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="BaseTypes.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="BuiltInFunctionEmulator.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ConstantUnion.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="debug.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="DetectCallDepth.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Diagnostics.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="DirectiveHandler.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ForLoopUnroll.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="InfoSink.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Initialize.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="InitializeDll.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="InitializeGlobals.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="InitializeParseContext.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="intermediate.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="localintermediate.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="MapLongVariableNames.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="MMap.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="osinclude.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="PoolAlloc.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="QualifierAlive.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="RemoveTree.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="RenameFunction.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\include\GLSLANG\ShaderLang.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ShHandle.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="SymbolTable.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Types.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="util.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ValidateLimitations.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="VariableInfo.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="VariablePacker.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="glslang_tab.h"> - <Filter>Header Files\generated</Filter> - </ClInclude> - <ClInclude Include="timing\RestrictFragmentShaderTiming.h"> - <Filter>Header Files\timing</Filter> - </ClInclude> - <ClInclude Include="timing\RestrictVertexShaderTiming.h"> - <Filter>Header Files\timing</Filter> - </ClInclude> - <ClInclude Include="depgraph\DependencyGraph.h"> - <Filter>Header Files\depgraph</Filter> - </ClInclude> - <ClInclude Include="depgraph\DependencyGraphBuilder.h"> - <Filter>Header Files\depgraph</Filter> - </ClInclude> - <ClInclude Include="depgraph\DependencyGraphOutput.h"> - <Filter>Header Files\depgraph</Filter> - </ClInclude> - <ClInclude Include="HashNames.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="InitializeGLPosition.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\third_party\compiler\ArrayBoundsClamper.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="DetectDiscontinuity.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="OutputHLSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="SearchSymbol.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="TranslatorHLSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="UnfoldShortCircuit.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Uniform.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="TranslatorGLSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="TranslatorESSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="OutputESSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="OutputGLSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="OutputGLSLBase.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="VersionGLSL.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="UnfoldShortCircuitAST.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ParseContext.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="NodeSearch.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="glslang.l"> - <Filter>Source Files</Filter> - </CustomBuild> - <CustomBuild Include="glslang.y"> - <Filter>Source Files</Filter> - </CustomBuild> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/64bit-lexer-safety.patch b/chromium/third_party/angle/src/compiler/translator/64bit-lexer-safety.patch index 7af91f57653..7af91f57653 100644 --- a/chromium/third_party/angle/src/compiler/64bit-lexer-safety.patch +++ b/chromium/third_party/angle/src/compiler/translator/64bit-lexer-safety.patch diff --git a/chromium/third_party/angle/src/compiler/translator/BaseTypes.h b/chromium/third_party/angle/src/compiler/translator/BaseTypes.h new file mode 100644 index 00000000000..ba9ef5e609e --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/BaseTypes.h @@ -0,0 +1,471 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef _BASICTYPES_INCLUDED_ +#define _BASICTYPES_INCLUDED_ + +#include <assert.h> + +// +// Precision qualifiers +// +enum TPrecision +{ + // These need to be kept sorted + EbpUndefined, + EbpLow, + EbpMedium, + EbpHigh +}; + +inline const char* getPrecisionString(TPrecision p) +{ + switch(p) + { + case EbpHigh: return "highp"; break; + case EbpMedium: return "mediump"; break; + case EbpLow: return "lowp"; break; + default: return "mediump"; break; // Safest fallback + } +} + +// +// Basic type. Arrays, vectors, etc., are orthogonal to this. +// +enum TBasicType +{ + EbtVoid, + EbtFloat, + EbtInt, + EbtUInt, + EbtBool, + EbtGVec4, // non type: represents vec4, ivec4 and uvec4 + EbtGuardSamplerBegin, // non type: see implementation of IsSampler() + EbtSampler2D, + EbtSampler3D, + EbtSamplerCube, + EbtSampler2DArray, + EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists. + EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists. + EbtISampler2D, + EbtISampler3D, + EbtISamplerCube, + EbtISampler2DArray, + EbtUSampler2D, + EbtUSampler3D, + EbtUSamplerCube, + EbtUSampler2DArray, + EbtSampler2DShadow, + EbtSamplerCubeShadow, + EbtSampler2DArrayShadow, + EbtGuardSamplerEnd, // non type: see implementation of IsSampler() + EbtGSampler2D, // non type: represents sampler2D, isampler2D and usampler2D + EbtGSampler3D, // non type: represents sampler3D, isampler3D and usampler3D + EbtGSamplerCube, // non type: represents samplerCube, isamplerCube and usamplerCube + EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray and usampler2DArray + EbtStruct, + EbtInterfaceBlock, + EbtAddress, // should be deprecated?? + EbtInvariant // used as a type when qualifying a previously declared variable as being invariant +}; + +inline const char* getBasicString(TBasicType t) +{ + switch (t) + { + case EbtVoid: return "void"; break; + case EbtFloat: return "float"; break; + case EbtInt: return "int"; break; + case EbtUInt: return "uint"; break; + case EbtBool: return "bool"; break; + case EbtSampler2D: return "sampler2D"; break; + case EbtSampler3D: return "sampler3D"; break; + case EbtSamplerCube: return "samplerCube"; break; + case EbtSamplerExternalOES: return "samplerExternalOES"; break; + case EbtSampler2DRect: return "sampler2DRect"; break; + case EbtSampler2DArray: return "sampler2DArray"; break; + case EbtISampler2D: return "isampler2D"; break; + case EbtISampler3D: return "isampler3D"; break; + case EbtISamplerCube: return "isamplerCube"; break; + case EbtISampler2DArray: return "isampler2DArray"; break; + case EbtUSampler2D: return "usampler2D"; break; + case EbtUSampler3D: return "usampler3D"; break; + case EbtUSamplerCube: return "usamplerCube"; break; + case EbtUSampler2DArray: return "usampler2DArray"; break; + case EbtSampler2DShadow: return "sampler2DShadow"; break; + case EbtSamplerCubeShadow: return "samplerCubeShadow"; break; + case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break; + case EbtStruct: return "structure"; break; + case EbtInterfaceBlock: return "interface block"; break; + default: return "unknown type"; + } +} + +inline bool IsSampler(TBasicType type) +{ + return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd; +} + +inline bool IsIntegerSampler(TBasicType type) +{ + switch (type) + { + case EbtISampler2D: + case EbtISampler3D: + case EbtISamplerCube: + case EbtISampler2DArray: + case EbtUSampler2D: + case EbtUSampler3D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + return true; + case EbtSampler2D: + case EbtSampler3D: + case EbtSamplerCube: + case EbtSamplerExternalOES: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsSampler2D(TBasicType type) +{ + switch (type) + { + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DRect: + case EbtSamplerExternalOES: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + return true; + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCube: + case EbtSamplerCubeShadow: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsSamplerCube(TBasicType type) +{ + switch (type) + { + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCubeShadow: + return true; + case EbtSampler2D: + case EbtSampler3D: + case EbtSamplerExternalOES: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtISampler2D: + case EbtISampler3D: + case EbtISampler2DArray: + case EbtUSampler2D: + case EbtUSampler3D: + case EbtUSampler2DArray: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsSampler3D(TBasicType type) +{ + switch (type) + { + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + return true; + case EbtSampler2D: + case EbtSamplerCube: + case EbtSamplerExternalOES: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtISampler2D: + case EbtISamplerCube: + case EbtISampler2DArray: + case EbtUSampler2D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsSamplerArray(TBasicType type) +{ + switch (type) + { + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DArrayShadow: + return true; + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DRect: + case EbtSamplerExternalOES: + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCube: + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsShadowSampler(TBasicType type) +{ + switch (type) + { + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + return true; + case EbtISampler2D: + case EbtISampler3D: + case EbtISamplerCube: + case EbtISampler2DArray: + case EbtUSampler2D: + case EbtUSampler3D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + case EbtSampler2D: + case EbtSampler3D: + case EbtSamplerCube: + case EbtSamplerExternalOES: + case EbtSampler2DRect: + case EbtSampler2DArray: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool SupportsPrecision(TBasicType type) +{ + return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type); +} + +// +// Qualifiers and built-ins. These are mainly used to see what can be read +// or written, and by the machine dependent translator to know which registers +// to allocate variables in. Since built-ins tend to go to different registers +// than varying or uniform, it makes sense they are peers, not sub-classes. +// +enum TQualifier +{ + EvqTemporary, // For temporaries (within a function), read/write + EvqGlobal, // For globals read/write + EvqInternal, // For internal use, not visible to the user + EvqConst, // User defined constants and non-output parameters in functions + EvqAttribute, // Readonly + EvqVaryingIn, // readonly, fragment shaders only + EvqVaryingOut, // vertex shaders only read/write + EvqInvariantVaryingIn, // readonly, fragment shaders only + EvqInvariantVaryingOut, // vertex shaders only read/write + EvqUniform, // Readonly, vertex and fragment + + EvqVertexIn, // Vertex shader input + EvqFragmentOut, // Fragment shader output + EvqVertexOut, // Vertex shader output + EvqFragmentIn, // Fragment shader input + + // parameters + EvqIn, + EvqOut, + EvqInOut, + EvqConstReadOnly, + + // built-ins written by vertex shader + EvqPosition, + EvqPointSize, + + // built-ins read by fragment shader + EvqFragCoord, + EvqFrontFacing, + EvqPointCoord, + + // built-ins written by fragment shader + EvqFragColor, + EvqFragData, + EvqFragDepth, + + // GLSL ES 3.0 vertex output and fragment input + EvqSmooth, // Incomplete qualifier, smooth is the default + EvqFlat, // Incomplete qualifier + EvqSmoothOut = EvqSmooth, + EvqFlatOut = EvqFlat, + EvqCentroidOut, // Implies smooth + EvqSmoothIn, + EvqFlatIn, + EvqCentroidIn, // Implies smooth + + // end of list + EvqLast +}; + +enum TLayoutMatrixPacking +{ + EmpUnspecified, + EmpRowMajor, + EmpColumnMajor +}; + +enum TLayoutBlockStorage +{ + EbsUnspecified, + EbsShared, + EbsPacked, + EbsStd140 +}; + +struct TLayoutQualifier +{ + int location; + TLayoutMatrixPacking matrixPacking; + TLayoutBlockStorage blockStorage; + + static TLayoutQualifier create() + { + TLayoutQualifier layoutQualifier; + + layoutQualifier.location = -1; + layoutQualifier.matrixPacking = EmpUnspecified; + layoutQualifier.blockStorage = EbsUnspecified; + + return layoutQualifier; + } + + bool isEmpty() const + { + return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified; + } +}; + +// +// This is just for debug print out, carried along with the definitions above. +// +inline const char* getQualifierString(TQualifier q) +{ + switch(q) + { + case EvqTemporary: return "Temporary"; break; + case EvqGlobal: return "Global"; break; + case EvqConst: return "const"; break; + case EvqConstReadOnly: return "const"; break; + case EvqAttribute: return "attribute"; break; + case EvqVaryingIn: return "varying"; break; + case EvqVaryingOut: return "varying"; break; + case EvqInvariantVaryingIn: return "invariant varying"; break; + case EvqInvariantVaryingOut:return "invariant varying"; break; + case EvqUniform: return "uniform"; break; + case EvqVertexIn: return "in"; break; + case EvqFragmentOut: return "out"; break; + case EvqVertexOut: return "out"; break; + case EvqFragmentIn: return "in"; break; + case EvqIn: return "in"; break; + case EvqOut: return "out"; break; + case EvqInOut: return "inout"; break; + case EvqPosition: return "Position"; break; + case EvqPointSize: return "PointSize"; break; + case EvqFragCoord: return "FragCoord"; break; + case EvqFrontFacing: return "FrontFacing"; break; + case EvqFragColor: return "FragColor"; break; + case EvqFragData: return "FragData"; break; + case EvqFragDepth: return "FragDepth"; break; + case EvqSmoothOut: return "smooth out"; break; + case EvqCentroidOut: return "centroid out"; break; + case EvqFlatOut: return "flat out"; break; + case EvqSmoothIn: return "smooth in"; break; + case EvqCentroidIn: return "centroid in"; break; + case EvqFlatIn: return "flat in"; break; + default: return "unknown qualifier"; + } +} + +inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq) +{ + switch (mpq) + { + case EmpUnspecified: return "mp_unspecified"; + case EmpRowMajor: return "row_major"; + case EmpColumnMajor: return "column_major"; + default: return "unknown matrix packing"; + } +} + +inline const char* getBlockStorageString(TLayoutBlockStorage bsq) +{ + switch (bsq) + { + case EbsUnspecified: return "bs_unspecified"; + case EbsShared: return "shared"; + case EbsPacked: return "packed"; + case EbsStd140: return "std140"; + default: return "unknown block storage"; + } +} + +inline const char* getInterpolationString(TQualifier q) +{ + switch(q) + { + case EvqSmoothOut: return "smooth"; break; + case EvqCentroidOut: return "centroid"; break; + case EvqFlatOut: return "flat"; break; + case EvqSmoothIn: return "smooth"; break; + case EvqCentroidIn: return "centroid"; break; + case EvqFlatIn: return "flat"; break; + default: return "unknown interpolation"; + } +} + +#endif // _BASICTYPES_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/BuiltInFunctionEmulator.cpp b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp index 1c4b25f13f0..afbc16926ff 100644 --- a/chromium/third_party/angle/src/compiler/BuiltInFunctionEmulator.cpp +++ b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp @@ -4,9 +4,9 @@ // found in the LICENSE file. // -#include "compiler/BuiltInFunctionEmulator.h" +#include "compiler/translator/BuiltInFunctionEmulator.h" -#include "compiler/SymbolTable.h" +#include "compiler/translator/SymbolTable.h" namespace { @@ -327,7 +327,7 @@ BuiltInFunctionEmulator::TBuiltInFunction BuiltInFunctionEmulator::IdentifyFunction( TOperator op, const TType& param) { - if (param.getNominalSize() > 4) + if (param.getNominalSize() > 4 || param.getSecondarySize() > 4) return TFunctionUnknown; unsigned int function = TFunctionUnknown; switch (op) { @@ -356,9 +356,9 @@ BuiltInFunctionEmulator::IdentifyFunction( { // Right now for all the emulated functions with two parameters, the two // parameters have the same type. - if (param1.isVector() != param2.isVector() || - param1.getNominalSize() != param2.getNominalSize() || - param1.getNominalSize() > 4) + if (param1.getNominalSize() != param2.getNominalSize() || + param1.getSecondarySize() != param2.getSecondarySize() || + param1.getNominalSize() > 4 || param1.getSecondarySize() > 4) return TFunctionUnknown; unsigned int function = TFunctionUnknown; diff --git a/chromium/third_party/angle/src/compiler/BuiltInFunctionEmulator.h b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.h index 0d904f41d09..9367b558ac0 100644 --- a/chromium/third_party/angle/src/compiler/BuiltInFunctionEmulator.h +++ b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.h @@ -7,10 +7,8 @@ #ifndef COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_ #define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_ -#include "GLSLANG/ShaderLang.h" - -#include "compiler/InfoSink.h" -#include "compiler/intermediate.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/intermediate.h" // // This class decides which built-in functions need to be replaced with the diff --git a/chromium/third_party/angle/src/compiler/CodeGen.cpp b/chromium/third_party/angle/src/compiler/translator/CodeGen.cpp index 24f21b87617..c35dbdc77ff 100644 --- a/chromium/third_party/angle/src/compiler/CodeGen.cpp +++ b/chromium/third_party/angle/src/compiler/translator/CodeGen.cpp @@ -1,12 +1,12 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/TranslatorESSL.h" -#include "compiler/TranslatorGLSL.h" -#include "compiler/TranslatorHLSL.h" +#include "compiler/translator/TranslatorESSL.h" +#include "compiler/translator/TranslatorGLSL.h" +#include "compiler/translator/TranslatorHLSL.h" // // This function must be provided to create the actual @@ -17,14 +17,14 @@ TCompiler* ConstructCompiler( ShShaderType type, ShShaderSpec spec, ShShaderOutput output) { switch (output) { - case SH_ESSL_OUTPUT: + case SH_ESSL_OUTPUT: return new TranslatorESSL(type, spec); - case SH_GLSL_OUTPUT: + case SH_GLSL_OUTPUT: return new TranslatorGLSL(type, spec); - case SH_HLSL9_OUTPUT: - case SH_HLSL11_OUTPUT: + case SH_HLSL9_OUTPUT: + case SH_HLSL11_OUTPUT: return new TranslatorHLSL(type, spec, output); - default: + default: return NULL; } } diff --git a/chromium/third_party/angle/src/compiler/Common.h b/chromium/third_party/angle/src/compiler/translator/Common.h index 46f9440fff1..1e4503e340c 100644 --- a/chromium/third_party/angle/src/compiler/Common.h +++ b/chromium/third_party/angle/src/compiler/translator/Common.h @@ -11,8 +11,12 @@ #include <sstream> #include <string> #include <vector> +#include <limits> +#include <stdio.h> -#include "compiler/PoolAlloc.h" +#include "compiler/translator/PoolAlloc.h" +#include "compiler/translator/compilerdebug.h" +#include "common/angleutils.h" struct TSourceLoc { int first_file; @@ -74,4 +78,15 @@ public: TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {} }; +// Integer to TString conversion +template <typename T> +inline TString str(T i) +{ + ASSERT(std::numeric_limits<T>::is_integer); + char buffer[((8 * sizeof(T)) / 3) + 3]; + const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u"; + snprintf(buffer, sizeof(buffer), formatStr, i); + return buffer; +} + #endif // _COMMON_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/Compiler.cpp b/chromium/third_party/angle/src/compiler/translator/Compiler.cpp index 54ca70826ae..402715b8af1 100644 --- a/chromium/third_party/angle/src/compiler/Compiler.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Compiler.cpp @@ -1,78 +1,101 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/BuiltInFunctionEmulator.h" -#include "compiler/DetectCallDepth.h" -#include "compiler/ForLoopUnroll.h" -#include "compiler/Initialize.h" -#include "compiler/InitializeGLPosition.h" -#include "compiler/InitializeParseContext.h" -#include "compiler/MapLongVariableNames.h" -#include "compiler/ParseContext.h" -#include "compiler/RenameFunction.h" -#include "compiler/ShHandle.h" -#include "compiler/UnfoldShortCircuitAST.h" -#include "compiler/ValidateLimitations.h" -#include "compiler/VariablePacker.h" -#include "compiler/depgraph/DependencyGraph.h" -#include "compiler/depgraph/DependencyGraphOutput.h" -#include "compiler/timing/RestrictFragmentShaderTiming.h" -#include "compiler/timing/RestrictVertexShaderTiming.h" +#include "compiler/translator/BuiltInFunctionEmulator.h" +#include "compiler/translator/DetectCallDepth.h" +#include "compiler/translator/ForLoopUnroll.h" +#include "compiler/translator/Initialize.h" +#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/InitializeVariables.h" +#include "compiler/translator/ParseContext.h" +#include "compiler/translator/RenameFunction.h" +#include "compiler/translator/ShHandle.h" +#include "compiler/translator/UnfoldShortCircuitAST.h" +#include "compiler/translator/ValidateLimitations.h" +#include "compiler/translator/ValidateOutputs.h" +#include "compiler/translator/VariablePacker.h" +#include "compiler/translator/depgraph/DependencyGraph.h" +#include "compiler/translator/depgraph/DependencyGraphOutput.h" +#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" +#include "compiler/translator/timing/RestrictVertexShaderTiming.h" #include "third_party/compiler/ArrayBoundsClamper.h" -bool isWebGLBasedSpec(ShShaderSpec spec) +bool IsWebGLBasedSpec(ShShaderSpec spec) { return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC; } +size_t GetGlobalMaxTokenSize(ShShaderSpec spec) +{ + // WebGL defines a max token legnth of 256, while ES2 leaves max token + // size undefined. ES3 defines a max size of 1024 characters. + if (IsWebGLBasedSpec(spec)) + { + return 256; + } + else + { + return 1024; + } +} + namespace { -class TScopedPoolAllocator { -public: - TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) { +class TScopedPoolAllocator +{ + public: + TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) + { mAllocator->push(); SetGlobalPoolAllocator(mAllocator); } - ~TScopedPoolAllocator() { + ~TScopedPoolAllocator() + { SetGlobalPoolAllocator(NULL); mAllocator->pop(); } -private: + private: TPoolAllocator* mAllocator; }; -class TScopedSymbolTableLevel { -public: - TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) { +class TScopedSymbolTableLevel +{ + public: + TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) + { ASSERT(mTable->atBuiltInLevel()); mTable->push(); } - ~TScopedSymbolTableLevel() { + ~TScopedSymbolTableLevel() + { while (!mTable->atBuiltInLevel()) mTable->pop(); } -private: + private: TSymbolTable* mTable; }; } // namespace -TShHandleBase::TShHandleBase() { +TShHandleBase::TShHandleBase() +{ allocator.push(); SetGlobalPoolAllocator(&allocator); } -TShHandleBase::~TShHandleBase() { +TShHandleBase::~TShHandleBase() +{ SetGlobalPoolAllocator(NULL); allocator.popAll(); } -TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec) +TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec, ShShaderOutput output) : shaderType(type), shaderSpec(spec), + outputType(output), maxUniformVectors(0), maxExpressionComplexity(0), maxCallStackDepth(0), @@ -80,17 +103,15 @@ TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec) clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC), builtInFunctionEmulator(type) { - longNameMap = LongNameMap::GetInstance(); } TCompiler::~TCompiler() { - ASSERT(longNameMap); - longNameMap->Release(); } bool TCompiler::Init(const ShBuiltInResources& resources) { + shaderVersion = 100; maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ? resources.MaxVertexUniformVectors : resources.MaxFragmentUniformVectors; @@ -124,7 +145,7 @@ bool TCompiler::compile(const char* const shaderStrings[], return true; // If compiling for WebGL, validate loop and indexing as well. - if (isWebGLBasedSpec(shaderSpec)) + if (IsWebGLBasedSpec(shaderSpec)) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. @@ -151,13 +172,24 @@ bool TCompiler::compile(const char* const shaderStrings[], bool success = (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); - if (success) { + + shaderVersion = parseContext.getShaderVersion(); + + if (success) + { TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); + // Disallow expressions deemed too complex. + if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) + success = limitExpressionComplexity(root); + if (success) success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0); + if (success && shaderVersion == 300 && shaderType == SH_FRAGMENT_SHADER) + success = validateOutputs(root); + if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); @@ -169,7 +201,21 @@ bool TCompiler::compile(const char* const shaderStrings[], // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) - ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root); + { + ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex); + root->traverse(&marker); + } + if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX)) + { + ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex); + root->traverse(&marker); + if (marker.samplerArrayIndexIsFloatLoopIndex()) + { + infoSink.info.prefix(EPrefixError); + infoSink.info << "sampler array index is float loop index"; + success = false; + } + } // Built-in function emulation needs to happen after validateLimitations pass. if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)) @@ -179,37 +225,31 @@ bool TCompiler::compile(const char* const shaderStrings[], if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); - // Disallow expressions deemed too complex. - if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) - success = limitExpressionComplexity(root); - - // Call mapLongVariableNames() before collectAttribsUniforms() so in - // collectAttribsUniforms() we already have the mapped symbol names and - // we could composite mapped and original variable names. - // Also, if we hash all the names, then no need to do this for long names. - if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL) - mapLongVariableNames(root); + if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) + initializeGLPosition(root); - if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) { - InitializeGLPosition initGLPosition; - root->traverse(&initGLPosition); - } - - if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { + if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) + { UnfoldShortCircuitAST unfoldShortCircuit; root->traverse(&unfoldShortCircuit); unfoldShortCircuit.updateTree(); - } + } - if (success && (compileOptions & SH_VARIABLES)) { + if (success && (compileOptions & SH_VARIABLES)) + { collectVariables(root); - if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { + if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) + { success = enforcePackingRestrictions(); - if (!success) { + if (!success) + { infoSink.info.prefix(EPrefixError); infoSink.info << "too many uniforms"; } } + if (success && shaderType == SH_VERTEX_SHADER && + (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) + initializeVaryingsWithoutStaticUse(root); } if (success && (compileOptions & SH_INTERMEDIATE_TREE)) @@ -221,32 +261,35 @@ bool TCompiler::compile(const char* const shaderStrings[], // Cleanup memory. intermediate.remove(parseContext.treeRoot); - + SetGlobalParseContext(NULL); return success; } bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) { compileResources = resources; + setResourceString(); assert(symbolTable.isEmpty()); - symbolTable.push(); + symbolTable.push(); // COMMON_BUILTINS + symbolTable.push(); // ESSL1_BUILTINS + symbolTable.push(); // ESSL3_BUILTINS TPublicType integer; integer.type = EbtInt; - integer.size = 1; - integer.matrix = false; + integer.primarySize = 1; + integer.secondarySize = 1; integer.array = false; TPublicType floatingPoint; floatingPoint.type = EbtFloat; - floatingPoint.size = 1; - floatingPoint.matrix = false; + floatingPoint.primarySize = 1; + floatingPoint.secondarySize = 1; floatingPoint.array = false; TPublicType sampler; - sampler.size = 1; - sampler.matrix = false; + sampler.primarySize = 1; + sampler.secondarySize = 1; sampler.array = false; switch(shaderType) @@ -258,12 +301,14 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) symbolTable.setDefaultPrecision(integer, EbpHigh); symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); break; - default: assert(false && "Language not supported"); + default: + assert(false && "Language not supported"); } // We set defaults for all the sampler types, even those that are // only available if an extension exists. for (int samplerType = EbtGuardSamplerBegin + 1; - samplerType < EbtGuardSamplerEnd; ++samplerType) { + samplerType < EbtGuardSamplerEnd; ++samplerType) + { sampler.type = static_cast<TBasicType>(samplerType); symbolTable.setDefaultPrecision(sampler, EbpLow); } @@ -275,6 +320,34 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) return true; } +void TCompiler::setResourceString() +{ + std::ostringstream strstream; + strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs + << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors + << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors + << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits + << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits + << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits + << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors + << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers + << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives + << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external + << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle + << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers + << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh + << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity + << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth + << ":EXT_frag_depth:" << compileResources.EXT_frag_depth + << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod + << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors + << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors + << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset + << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset; + + builtInResourcesString = strstream.str(); +} + void TCompiler::clearResults() { arrayBoundsClamper.Cleanup(); @@ -295,34 +368,43 @@ bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool lim { DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth); root->traverse(&detect); - switch (detect.detectCallDepth()) { - case DetectCallDepth::kErrorNone: - return true; - case DetectCallDepth::kErrorMissingMain: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Missing main()"; - return false; - case DetectCallDepth::kErrorRecursion: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Function recursion detected"; - return false; - case DetectCallDepth::kErrorMaxDepthExceeded: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Function call stack too deep"; - return false; - default: - UNREACHABLE(); - return false; + switch (detect.detectCallDepth()) + { + case DetectCallDepth::kErrorNone: + return true; + case DetectCallDepth::kErrorMissingMain: + infoSink.info.prefix(EPrefixError); + infoSink.info << "Missing main()"; + return false; + case DetectCallDepth::kErrorRecursion: + infoSink.info.prefix(EPrefixError); + infoSink.info << "Function recursion detected"; + return false; + case DetectCallDepth::kErrorMaxDepthExceeded: + infoSink.info.prefix(EPrefixError); + infoSink.info << "Function call stack too deep"; + return false; + default: + UNREACHABLE(); + return false; } } +bool TCompiler::validateOutputs(TIntermNode* root) +{ + ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers); + root->traverse(&validateOutputs); + return (validateOutputs.numErrors() == 0); +} + void TCompiler::rewriteCSSShader(TIntermNode* root) { RenameFunction renamer("main(", "css_main("); root->traverse(&renamer); } -bool TCompiler::validateLimitations(TIntermNode* root) { +bool TCompiler::validateLimitations(TIntermNode* root) +{ ValidateLimitations validate(shaderType, infoSink.info); root->traverse(&validate); return validate.numErrors() == 0; @@ -330,34 +412,45 @@ bool TCompiler::validateLimitations(TIntermNode* root) { bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph) { - if (shaderSpec != SH_WEBGL_SPEC) { + if (shaderSpec != SH_WEBGL_SPEC) + { infoSink.info << "Timing restrictions must be enforced under the WebGL spec."; return false; } - if (shaderType == SH_FRAGMENT_SHADER) { + if (shaderType == SH_FRAGMENT_SHADER) + { TDependencyGraph graph(root); // Output any errors first. bool success = enforceFragmentShaderTimingRestrictions(graph); - + // Then, output the dependency graph. - if (outputGraph) { + if (outputGraph) + { TDependencyGraphOutput output(infoSink.info); output.outputAllSpanningTrees(graph); } - + return success; } - else { + else + { return enforceVertexShaderTimingRestrictions(root); } } bool TCompiler::limitExpressionComplexity(TIntermNode* root) { - TIntermTraverser traverser; + TMaxDepthTraverser traverser(maxExpressionComplexity+1); root->traverse(&traverser); + + if (traverser.getMaxDepth() > maxExpressionComplexity) + { + infoSink.info << "Expression too complex."; + return false; + } + TDependencyGraph graph(root); for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls(); @@ -369,10 +462,6 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root) samplerSymbol->traverse(&graphTraverser); } - if (traverser.getMaxDepth() > maxExpressionComplexity) { - infoSink.info << "Expression too complex."; - return false; - } return true; } @@ -402,16 +491,66 @@ bool TCompiler::enforcePackingRestrictions() return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms); } -void TCompiler::mapLongVariableNames(TIntermNode* root) +void TCompiler::initializeGLPosition(TIntermNode* root) { - ASSERT(longNameMap); - MapLongVariableNames map(longNameMap); - root->traverse(&map); + InitializeVariables::InitVariableInfoList variables; + InitializeVariables::InitVariableInfo var( + "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4)); + variables.push_back(var); + InitializeVariables initializer(variables); + root->traverse(&initializer); } -int TCompiler::getMappedNameMaxLength() const +void TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root) { - return MAX_SHORTENED_IDENTIFIER_SIZE + 1; + InitializeVariables::InitVariableInfoList variables; + for (size_t ii = 0; ii < varyings.size(); ++ii) + { + const TVariableInfo& varying = varyings[ii]; + if (varying.staticUse) + continue; + unsigned char primarySize = 1, secondarySize = 1; + switch (varying.type) + { + case SH_FLOAT: + break; + case SH_FLOAT_VEC2: + primarySize = 2; + break; + case SH_FLOAT_VEC3: + primarySize = 3; + break; + case SH_FLOAT_VEC4: + primarySize = 4; + break; + case SH_FLOAT_MAT2: + primarySize = 2; + secondarySize = 2; + break; + case SH_FLOAT_MAT3: + primarySize = 3; + secondarySize = 3; + break; + case SH_FLOAT_MAT4: + primarySize = 4; + secondarySize = 4; + break; + default: + ASSERT(false); + } + TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray); + TString name = varying.name.c_str(); + if (varying.isArray) + { + type.setArraySize(varying.size); + name = name.substr(0, name.find_first_of('[')); + } + + InitializeVariables::InitVariableInfo var(name, type); + variables.push_back(var); + } + InitializeVariables initializer(variables); + root->traverse(&initializer); } const TExtensionBehavior& TCompiler::getExtensionBehavior() const diff --git a/chromium/third_party/angle/src/compiler/ConstantUnion.h b/chromium/third_party/angle/src/compiler/translator/ConstantUnion.h index b1e37885f90..5fdba61546c 100644 --- a/chromium/third_party/angle/src/compiler/ConstantUnion.h +++ b/chromium/third_party/angle/src/compiler/translator/ConstantUnion.h @@ -19,13 +19,12 @@ public: } void setIConst(int i) {iConst = i; type = EbtInt; } + void setUConst(unsigned int u) { uConst = u; type = EbtUInt; } void setFConst(float f) {fConst = f; type = EbtFloat; } void setBConst(bool b) {bConst = b; type = EbtBool; } - int getIConst() { return iConst; } - float getFConst() { return fConst; } - bool getBConst() { return bConst; } int getIConst() const { return iConst; } + unsigned int getUConst() const { return uConst; } float getFConst() const { return fConst; } bool getBConst() const { return bConst; } @@ -34,6 +33,11 @@ public: return i == iConst; } + bool operator==(const unsigned int u) const + { + return u == uConst; + } + bool operator==(const float f) const { return f == fConst; @@ -52,6 +56,8 @@ public: switch (type) { case EbtInt: return constant.iConst == iConst; + case EbtUInt: + return constant.uConst == uConst; case EbtFloat: return constant.fConst == fConst; case EbtBool: @@ -66,6 +72,11 @@ public: return !operator==(i); } + bool operator!=(const unsigned int u) const + { + return !operator==(u); + } + bool operator!=(const float f) const { return !operator==(f); @@ -87,6 +98,8 @@ public: switch (type) { case EbtInt: return iConst > constant.iConst; + case EbtUInt: + return uConst > constant.uConst; case EbtFloat: return fConst > constant.fConst; default: @@ -100,6 +113,8 @@ public: switch (type) { case EbtInt: return iConst < constant.iConst; + case EbtUInt: + return uConst < constant.uConst; case EbtFloat: return fConst < constant.fConst; default: @@ -113,6 +128,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break; case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break; default: assert(false && "Default missing"); } @@ -126,6 +142,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break; case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break; default: assert(false && "Default missing"); } @@ -139,6 +156,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break; case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; default: assert(false && "Default missing"); } @@ -152,6 +170,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break; default: assert(false && "Default missing"); } @@ -164,6 +183,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break; default: assert(false && "Default missing"); } @@ -176,6 +196,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break; default: assert(false && "Default missing"); } @@ -188,6 +209,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break; default: assert(false && "Default missing"); } @@ -200,6 +222,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break; default: assert(false && "Default missing"); } @@ -212,6 +235,7 @@ public: assert(type == constant.type); switch (type) { case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; + case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break; default: assert(false && "Default missing"); } @@ -247,6 +271,7 @@ private: union { int iConst; // used for ivec, scalar ints + unsigned int uConst; // used for uvec, scalar uints bool bConst; // used for bvec, scalar bools float fConst; // used for vec, mat, scalar floats } ; diff --git a/chromium/third_party/angle/src/compiler/DetectCallDepth.cpp b/chromium/third_party/angle/src/compiler/translator/DetectCallDepth.cpp index 60df52c7151..bfc1d5852ff 100644 --- a/chromium/third_party/angle/src/compiler/DetectCallDepth.cpp +++ b/chromium/third_party/angle/src/compiler/translator/DetectCallDepth.cpp @@ -4,8 +4,8 @@ // found in the LICENSE file. // -#include "compiler/DetectCallDepth.h" -#include "compiler/InfoSink.h" +#include "compiler/translator/DetectCallDepth.h" +#include "compiler/translator/InfoSink.h" DetectCallDepth::FunctionNode::FunctionNode(const TString& fname) : name(fname), diff --git a/chromium/third_party/angle/src/compiler/DetectCallDepth.h b/chromium/third_party/angle/src/compiler/translator/DetectCallDepth.h index 89e85f88f6e..cb76f1de02a 100644 --- a/chromium/third_party/angle/src/compiler/DetectCallDepth.h +++ b/chromium/third_party/angle/src/compiler/translator/DetectCallDepth.h @@ -7,11 +7,9 @@ #ifndef COMPILER_DETECT_RECURSION_H_ #define COMPILER_DETECT_RECURSION_H_ -#include "GLSLANG/ShaderLang.h" - #include <limits.h> -#include "compiler/intermediate.h" -#include "compiler/VariableInfo.h" +#include "compiler/translator/intermediate.h" +#include "compiler/translator/VariableInfo.h" class TInfoSink; diff --git a/chromium/third_party/angle/src/compiler/DetectDiscontinuity.cpp b/chromium/third_party/angle/src/compiler/translator/DetectDiscontinuity.cpp index 8cfe49ba224..334eb0bfa8b 100644 --- a/chromium/third_party/angle/src/compiler/DetectDiscontinuity.cpp +++ b/chromium/third_party/angle/src/compiler/translator/DetectDiscontinuity.cpp @@ -8,9 +8,9 @@ // gradients of functions with discontinuities. // -#include "compiler/DetectDiscontinuity.h" +#include "compiler/translator/DetectDiscontinuity.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/ParseContext.h" namespace sh { diff --git a/chromium/third_party/angle/src/compiler/DetectDiscontinuity.h b/chromium/third_party/angle/src/compiler/translator/DetectDiscontinuity.h index e5520bd5b02..1dd8be92335 100644 --- a/chromium/third_party/angle/src/compiler/DetectDiscontinuity.h +++ b/chromium/third_party/angle/src/compiler/translator/DetectDiscontinuity.h @@ -11,7 +11,7 @@ #ifndef COMPILER_DETECTDISCONTINUITY_H_ #define COMPILER_DETECTDISCONTINUITY_H_ -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" namespace sh { diff --git a/chromium/third_party/angle/src/compiler/Diagnostics.cpp b/chromium/third_party/angle/src/compiler/translator/Diagnostics.cpp index 1c1b9b5ed53..92db3e55cfb 100644 --- a/chromium/third_party/angle/src/compiler/Diagnostics.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Diagnostics.cpp @@ -1,13 +1,13 @@ // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/Diagnostics.h" +#include "compiler/translator/Diagnostics.h" -#include "compiler/debug.h" -#include "compiler/InfoSink.h" +#include "compiler/translator/compilerdebug.h" +#include "compiler/translator/InfoSink.h" #include "compiler/preprocessor/SourceLocation.h" TDiagnostics::TDiagnostics(TInfoSink& infoSink) : diff --git a/chromium/third_party/angle/src/compiler/Diagnostics.h b/chromium/third_party/angle/src/compiler/translator/Diagnostics.h index cb71bb12042..664da7803b8 100644 --- a/chromium/third_party/angle/src/compiler/Diagnostics.h +++ b/chromium/third_party/angle/src/compiler/translator/Diagnostics.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // diff --git a/chromium/third_party/angle/src/compiler/DirectiveHandler.cpp b/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.cpp index 6d3d831a399..59d2835f7b7 100644 --- a/chromium/third_party/angle/src/compiler/DirectiveHandler.cpp +++ b/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.cpp @@ -1,15 +1,15 @@ // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/DirectiveHandler.h" +#include "compiler/translator/DirectiveHandler.h" #include <sstream> -#include "compiler/debug.h" -#include "compiler/Diagnostics.h" +#include "compiler/translator/compilerdebug.h" +#include "compiler/translator/Diagnostics.h" static TBehavior getBehavior(const std::string& str) { @@ -26,9 +26,11 @@ static TBehavior getBehavior(const std::string& str) } TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior, - TDiagnostics& diagnostics) + TDiagnostics& diagnostics, + int& shaderVersion) : mExtensionBehavior(extBehavior), - mDiagnostics(diagnostics) + mDiagnostics(diagnostics), + mShaderVersion(shaderVersion) { } @@ -148,9 +150,12 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, int version) { - static const int kVersion = 100; - - if (version != kVersion) + if (version == 100 || + version == 300) + { + mShaderVersion = version; + } + else { std::stringstream stream; stream << version; diff --git a/chromium/third_party/angle/src/compiler/DirectiveHandler.h b/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.h index 95ca59d6fe5..69418c277af 100644 --- a/chromium/third_party/angle/src/compiler/DirectiveHandler.h +++ b/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.h @@ -7,8 +7,8 @@ #ifndef COMPILER_DIRECTIVE_HANDLER_H_ #define COMPILER_DIRECTIVE_HANDLER_H_ -#include "compiler/ExtensionBehavior.h" -#include "compiler/Pragma.h" +#include "compiler/translator/ExtensionBehavior.h" +#include "compiler/translator/Pragma.h" #include "compiler/preprocessor/DirectiveHandlerBase.h" class TDiagnostics; @@ -17,7 +17,8 @@ class TDirectiveHandler : public pp::DirectiveHandler { public: TDirectiveHandler(TExtensionBehavior& extBehavior, - TDiagnostics& diagnostics); + TDiagnostics& diagnostics, + int& shaderVersion); virtual ~TDirectiveHandler(); const TPragma& pragma() const { return mPragma; } @@ -41,6 +42,7 @@ class TDirectiveHandler : public pp::DirectiveHandler TPragma mPragma; TExtensionBehavior& mExtensionBehavior; TDiagnostics& mDiagnostics; + int& mShaderVersion; }; #endif // COMPILER_DIRECTIVE_HANDLER_H_ diff --git a/chromium/third_party/angle/src/compiler/ExtensionBehavior.h b/chromium/third_party/angle/src/compiler/translator/ExtensionBehavior.h index 5c1595fb212..5c1595fb212 100644 --- a/chromium/third_party/angle/src/compiler/ExtensionBehavior.h +++ b/chromium/third_party/angle/src/compiler/translator/ExtensionBehavior.h diff --git a/chromium/third_party/angle/src/compiler/translator/FlagStd140Structs.cpp b/chromium/third_party/angle/src/compiler/translator/FlagStd140Structs.cpp new file mode 100644 index 00000000000..a751b768b78 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/FlagStd140Structs.cpp @@ -0,0 +1,77 @@ +// +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/FlagStd140Structs.h" + +namespace sh +{ + +bool FlagStd140Structs::visitBinary(Visit visit, TIntermBinary *binaryNode) +{ + if (binaryNode->getRight()->getBasicType() == EbtStruct) + { + switch (binaryNode->getOp()) + { + case EOpIndexDirectInterfaceBlock: + case EOpIndexDirectStruct: + if (isInStd140InterfaceBlock(binaryNode->getLeft())) + { + mFlaggedNodes.push_back(binaryNode); + } + break; + + default: break; + } + return false; + } + + if (binaryNode->getOp() == EOpIndexDirectStruct) + { + return false; + } + + return visit == PreVisit; +} + +void FlagStd140Structs::visitSymbol(TIntermSymbol *symbol) +{ + if (isInStd140InterfaceBlock(symbol) && symbol->getBasicType() == EbtStruct) + { + mFlaggedNodes.push_back(symbol); + } +} + +bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const +{ + TIntermBinary *binaryNode = node->getAsBinaryNode(); + + if (binaryNode) + { + return isInStd140InterfaceBlock(binaryNode->getLeft()); + } + + const TType &type = node->getType(); + + // determine if we are in the standard layout + const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); + if (interfaceBlock) + { + return (interfaceBlock->blockStorage() == EbsStd140); + } + + return false; +} + +std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node) +{ + FlagStd140Structs flaggingTraversal; + + node->traverse(&flaggingTraversal); + + return flaggingTraversal.getFlaggedNodes(); +} + +} diff --git a/chromium/third_party/angle/src/compiler/translator/FlagStd140Structs.h b/chromium/third_party/angle/src/compiler/translator/FlagStd140Structs.h new file mode 100644 index 00000000000..610205eb92e --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/FlagStd140Structs.h @@ -0,0 +1,37 @@ +// +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_FLAGSTD140STRUCTS_H_ +#define COMPILER_FLAGSTD140STRUCTS_H_ + +#include "compiler/translator/intermediate.h" + +namespace sh +{ + +// This class finds references to nested structs of std140 blocks that access +// the nested struct "by value", where the padding added in the translator +// conflicts with the "natural" unpadded type. +class FlagStd140Structs : public TIntermTraverser +{ + public: + const std::vector<TIntermTyped *> getFlaggedNodes() const { return mFlaggedNodes; } + + protected: + virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode); + virtual void visitSymbol(TIntermSymbol *symbol); + + private: + bool isInStd140InterfaceBlock(TIntermTyped *node) const; + + std::vector<TIntermTyped *> mFlaggedNodes; +}; + +std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node); + +} + +#endif // COMPILER_FLAGSTD140STRUCTS_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp b/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp new file mode 100644 index 00000000000..5cb51645593 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp @@ -0,0 +1,82 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/ForLoopUnroll.h" + +bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node) +{ + if (mUnrollCondition != kSamplerArrayIndex) + return true; + + // If a sampler array index is also the loop index, + // 1) if the index type is integer, mark the loop for unrolling; + // 2) if the index type if float, set a flag to later fail compile. + switch (node->getOp()) + { + case EOpIndexIndirect: + if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode()) + { + TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode(); + if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty()) + { + mVisitSamplerArrayIndexNodeInsideLoop = true; + node->getRight()->traverse(this); + mVisitSamplerArrayIndexNodeInsideLoop = false; + // We have already visited all the children. + return false; + } + } + break; + default: + break; + } + return true; +} + +bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) +{ + if (mUnrollCondition == kIntegerIndex) + { + // Check if loop index type is integer. + // This is called after ValidateLimitations pass, so all the calls + // should be valid. See ValidateLimitations::validateForLoopInit(). + TIntermSequence& declSeq = node->getInit()->getAsAggregate()->getSequence(); + TIntermSymbol* symbol = declSeq[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); + if (symbol->getBasicType() == EbtInt) + node->setUnrollFlag(true); + } + + TIntermNode *body = node->getBody(); + if (body != NULL) + { + mLoopStack.push(node); + body->traverse(this); + mLoopStack.pop(); + } + // The loop is fully processed - no need to visit children. + return false; +} + +void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol) +{ + if (!mVisitSamplerArrayIndexNodeInsideLoop) + return; + TIntermLoop *loop = mLoopStack.findLoop(symbol); + if (loop) + { + switch (symbol->getBasicType()) + { + case EbtFloat: + mSamplerArrayIndexIsFloatLoopIndex = true; + break; + case EbtInt: + loop->setUnrollFlag(true); + break; + default: + UNREACHABLE(); + } + } +} diff --git a/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.h b/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.h new file mode 100644 index 00000000000..a820d2a20d6 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.h @@ -0,0 +1,50 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_FORLOOPUNROLL_H_ +#define COMPILER_FORLOOPUNROLL_H_ + +#include "compiler/translator/LoopInfo.h" + +// This class detects for-loops that needs to be unrolled. +// Currently we support two unroll conditions: +// 1) kForLoopWithIntegerIndex: unroll if the index type is integer. +// 2) kForLoopWithSamplerArrayIndex: unroll where a sampler array index +// is also the loop integer index, and reject and fail a compile +// where a sampler array index is also the loop float index. +class ForLoopUnrollMarker : public TIntermTraverser +{ + public: + enum UnrollCondition + { + kIntegerIndex, + kSamplerArrayIndex + }; + + ForLoopUnrollMarker(UnrollCondition condition) + : mUnrollCondition(condition), + mSamplerArrayIndexIsFloatLoopIndex(false), + mVisitSamplerArrayIndexNodeInsideLoop(false) + { + } + + virtual bool visitBinary(Visit, TIntermBinary *node); + virtual bool visitLoop(Visit, TIntermLoop *node); + virtual void visitSymbol(TIntermSymbol *node); + + bool samplerArrayIndexIsFloatLoopIndex() const + { + return mSamplerArrayIndexIsFloatLoopIndex; + } + + private: + UnrollCondition mUnrollCondition; + TLoopStack mLoopStack; + bool mSamplerArrayIndexIsFloatLoopIndex; + bool mVisitSamplerArrayIndexNodeInsideLoop; +}; + +#endif diff --git a/chromium/third_party/angle/src/compiler/HashNames.h b/chromium/third_party/angle/src/compiler/translator/HashNames.h index d2141e2d853..85161428b2a 100644 --- a/chromium/third_party/angle/src/compiler/HashNames.h +++ b/chromium/third_party/angle/src/compiler/translator/HashNames.h @@ -9,8 +9,7 @@ #include <map> -#include "compiler/intermediate.h" -#include "GLSLANG/ShaderLang.h" +#include "compiler/translator/intermediate.h" #define HASHED_NAME_PREFIX "webgl_" diff --git a/chromium/third_party/angle/src/compiler/InfoSink.cpp b/chromium/third_party/angle/src/compiler/translator/InfoSink.cpp index d20a6c0175a..cd59658ff76 100644 --- a/chromium/third_party/angle/src/compiler/InfoSink.cpp +++ b/chromium/third_party/angle/src/compiler/translator/InfoSink.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/InfoSink.h" +#include "compiler/translator/InfoSink.h" void TInfoSinkBase::prefix(TPrefixType p) { switch(p) { diff --git a/chromium/third_party/angle/src/compiler/InfoSink.h b/chromium/third_party/angle/src/compiler/translator/InfoSink.h index be0ddffe31f..698a8b454b3 100644 --- a/chromium/third_party/angle/src/compiler/InfoSink.h +++ b/chromium/third_party/angle/src/compiler/translator/InfoSink.h @@ -9,7 +9,7 @@ #include <math.h> #include <stdlib.h> -#include "compiler/Common.h" +#include "compiler/translator/Common.h" // Returns the fractional part of the given floating-point number. inline float fractionalPart(float f) { diff --git a/chromium/third_party/angle/src/compiler/translator/Initialize.cpp b/chromium/third_party/angle/src/compiler/translator/Initialize.cpp new file mode 100644 index 00000000000..27e96f4014a --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/Initialize.cpp @@ -0,0 +1,760 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// +// Create symbols that declare built-in definitions, add built-ins that +// cannot be expressed in the files, and establish mappings between +// built-in functions and operators. +// + +#include "compiler/translator/Initialize.h" + +#include "compiler/translator/intermediate.h" + +void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable) +{ + TType *float1 = new TType(EbtFloat); + TType *float2 = new TType(EbtFloat, 2); + TType *float3 = new TType(EbtFloat, 3); + TType *float4 = new TType(EbtFloat, 4); + + TType *int1 = new TType(EbtInt); + TType *int2 = new TType(EbtInt, 2); + TType *int3 = new TType(EbtInt, 3); + TType *int4 = new TType(EbtInt, 4); + + // + // Angle and Trigonometric Functions. + // + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "radians", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "radians", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "radians", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "radians", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "degrees", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "degrees", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "degrees", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "degrees", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sin", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sin", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sin", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sin", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "cos", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "cos", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "cos", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "cos", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "tan", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "tan", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "tan", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "tan", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "asin", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "asin", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "asin", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "asin", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "acos", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "acos", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "acos", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "acos", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "atan", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "atan", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "atan", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "atan", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "atan", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "atan", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "atan", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "atan", float4); + + // + // Exponential Functions. + // + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "pow", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "pow", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "pow", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "pow", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "exp", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "exp", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "exp", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "exp", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "log", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "log", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "log", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "log", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "exp2", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "exp2", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "exp2", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "exp2", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "log2", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "log2", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "log2", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "log2", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sqrt", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sqrt", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sqrt", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sqrt", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "inversesqrt", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "inversesqrt", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "inversesqrt", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "inversesqrt", float4); + + // + // Common Functions. + // + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "abs", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "abs", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "abs", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "abs", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sign", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sign", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sign", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sign", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "floor", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "floor", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "floor", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "floor", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "ceil", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "ceil", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "ceil", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "ceil", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "fract", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "fract", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "fract", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "fract", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "mod", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mod", float2, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mod", float3, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mod", float4, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mod", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mod", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mod", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "min", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "min", float2, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "min", float3, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "min", float4, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "min", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "min", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "min", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "max", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "max", float2, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "max", float3, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "max", float4, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "max", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "max", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "max", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "clamp", float1, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "clamp", float2, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "clamp", float3, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "clamp", float4, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "clamp", float2, float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "clamp", float3, float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "clamp", float4, float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "mix", float1, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mix", float2, float2, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mix", float3, float3, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mix", float4, float4, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mix", float2, float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mix", float3, float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mix", float4, float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "step", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "step", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "step", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "step", float4, float4); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "step", float1, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "step", float1, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "step", float1, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "smoothstep", float1, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "smoothstep", float2, float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float3, float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float4, float4, float4); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "smoothstep", float1, float1, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float1, float1, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float1, float1, float4); + + // + // Geometric Functions. + // + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "cross", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "normalize", float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "normalize", float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "normalize", float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "normalize", float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "faceforward", float1, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "faceforward", float2, float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "faceforward", float3, float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "faceforward", float4, float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "reflect", float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "reflect", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "reflect", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "reflect", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "refract", float1, float1, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "refract", float2, float2, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "refract", float3, float3, float1); + symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "refract", float4, float4, float1); + + TType *mat2 = new TType(EbtFloat, 2, 2); + TType *mat3 = new TType(EbtFloat, 3, 3); + TType *mat4 = new TType(EbtFloat, 4, 4); + + // + // Matrix Functions. + // + symbolTable.insertBuiltIn(COMMON_BUILTINS, mat2, "matrixCompMult", mat2, mat2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, mat3, "matrixCompMult", mat3, mat3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, mat4, "matrixCompMult", mat4, mat4); + + TType *bool1 = new TType(EbtBool); + TType *bool2 = new TType(EbtBool, 2); + TType *bool3 = new TType(EbtBool, 3); + TType *bool4 = new TType(EbtBool, 4); + + // + // Vector relational functions. + // + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThan", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThan", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThan", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThan", int2, int2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThan", int3, int3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThan", int4, int4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThanEqual", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThanEqual", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThanEqual", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThanEqual", int2, int2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThanEqual", int3, int3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThanEqual", int4, int4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThan", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThan", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThan", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThan", int2, int2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThan", int3, int3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThan", int4, int4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThanEqual", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThanEqual", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThanEqual", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThanEqual", int2, int2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThanEqual", int3, int3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThanEqual", int4, int4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", int2, int2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", int3, int3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", int4, int4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", bool2, bool2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", bool3, bool3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", bool4, bool4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", float2, float2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", float3, float3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", float4, float4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", int2, int2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", int3, int3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", int4, int4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", bool2, bool2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", bool3, bool3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", bool4, bool4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool4); + + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "not", bool2); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "not", bool3); + symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "not", bool4); + + TType *sampler2D = new TType(EbtSampler2D); + TType *samplerCube = new TType(EbtSamplerCube); + + // + // Texture Functions for GLSL ES 1.0 + // + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3); + + if (resources.OES_EGL_image_external) + { + TType *samplerExternalOES = new TType(EbtSamplerExternalOES); + + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4); + } + + if (resources.ARB_texture_rectangle) + { + TType *sampler2DRect = new TType(EbtSampler2DRect); + + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float4); + } + + if (resources.EXT_shader_texture_lod) + { + /* The *Grad* variants are new to both vertex and fragment shaders; the fragment + * shader specific pieces are added separately below. + */ + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DGradEXT", sampler2D, float2, float2, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeGradEXT", samplerCube, float3, float3, float3); + } + + if (type == SH_FRAGMENT_SHADER) + { + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1); + + if (resources.OES_standard_derivatives) + { + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "dFdx", float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "dFdx", float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "dFdx", float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "dFdx", float4); + + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "dFdy", float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "dFdy", float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "dFdy", float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "dFdy", float4); + + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "fwidth", float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "fwidth", float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "fwidth", float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "fwidth", float4); + } + + if (resources.EXT_shader_texture_lod) + { + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLodEXT", sampler2D, float2, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLodEXT", sampler2D, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLodEXT", sampler2D, float4, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLodEXT", samplerCube, float3, float1); + } + } + + if(type == SH_VERTEX_SHADER) + { + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, float1); + } + + TType *gvec4 = new TType(EbtGVec4); + + TType *gsampler2D = new TType(EbtGSampler2D); + TType *gsamplerCube = new TType(EbtGSamplerCube); + TType *gsampler3D = new TType(EbtGSampler3D); + TType *gsampler2DArray = new TType(EbtGSampler2DArray); + + // + // Texture Functions for GLSL ES 3.0 + // + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1); + + if (type == SH_FRAGMENT_SHADER) + { + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1); + } + + TType *sampler2DShadow = new TType(EbtSampler2DShadow); + TType *samplerCubeShadow = new TType(EbtSamplerCubeShadow); + TType *sampler2DArrayShadow = new TType(EbtSampler2DArrayShadow); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, float1); + + if (type == SH_FRAGMENT_SHADER) + { + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4, float1); + } + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler3D, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsamplerCube, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1); + + if(type == SH_FRAGMENT_SHADER) + { + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdx", float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdx", float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "dFdx", float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "dFdx", float4); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdy", float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdy", float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "dFdy", float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "dFdy", float4); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "fwidth", float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "fwidth", float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "fwidth", float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "fwidth", float4); + } + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2); + + if(type == SH_FRAGMENT_SHADER) + { + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2, float1); + } + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2); + + if(type == SH_FRAGMENT_SHADER) + { + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2, float1); + } + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3, float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3, float1, int2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float4, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler3D, float4, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4, float1); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3, float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, float1, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, float4, float1, int2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, float3, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, float2, float2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2, float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3, float3, float3, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3, float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3, float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow, float4, float2, float2, int2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4, float2, float2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3, float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4, float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3, float3, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2, float2, int2); + + // + // Depth range in window coordinates + // + TFieldList *fields = NewPoolTFieldList(); + TSourceLoc zeroSourceLoc = {0, 0, 0, 0}; + TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), zeroSourceLoc); + TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), zeroSourceLoc); + TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), zeroSourceLoc); + fields->push_back(near); + fields->push_back(far); + fields->push_back(diff); + TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields); + TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true); + symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters); + TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct)); + depthRange->setQualifier(EvqUniform); + symbolTable.insert(COMMON_BUILTINS, *depthRange); + + // + // Implementation dependent built-in constants. + // + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors); + + symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors); + + if (spec != SH_CSS_SHADERS_SPEC) + { + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers); + } + + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset); +} + +void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, + const ShBuiltInResources &resources, + TSymbolTable &symbolTable) +{ + // + // First, insert some special built-in variables that are not in + // the built-in header files. + // + switch(type) { + case SH_FRAGMENT_SHADER: + symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); + symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); + symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); + + // + // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available. + // Instead, css_MixColor and css_ColorMatrix are available. + // + if (spec != SH_CSS_SHADERS_SPEC) { + symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); + symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); + if (resources.EXT_frag_depth) { + symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1))); + symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_FragDepthEXT", "GL_EXT_frag_depth"); + } + } else { + symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4))); + symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4))); + } + + break; + + case SH_VERTEX_SHADER: + symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4))); + symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1))); + break; + + default: assert(false && "Language not supported"); + } + + // + // Next, identify which built-ins from the already loaded headers have + // a mapping to an operator. Those that are not identified as such are + // expected to be resolved through a library of functions, versus as + // operations. + // + symbolTable.relateToOperator(COMMON_BUILTINS, "matrixCompMult", EOpMul); + + symbolTable.relateToOperator(COMMON_BUILTINS, "equal", EOpVectorEqual); + symbolTable.relateToOperator(COMMON_BUILTINS, "notEqual", EOpVectorNotEqual); + symbolTable.relateToOperator(COMMON_BUILTINS, "lessThan", EOpLessThan); + symbolTable.relateToOperator(COMMON_BUILTINS, "greaterThan", EOpGreaterThan); + symbolTable.relateToOperator(COMMON_BUILTINS, "lessThanEqual", EOpLessThanEqual); + symbolTable.relateToOperator(COMMON_BUILTINS, "greaterThanEqual", EOpGreaterThanEqual); + + symbolTable.relateToOperator(COMMON_BUILTINS, "radians", EOpRadians); + symbolTable.relateToOperator(COMMON_BUILTINS, "degrees", EOpDegrees); + symbolTable.relateToOperator(COMMON_BUILTINS, "sin", EOpSin); + symbolTable.relateToOperator(COMMON_BUILTINS, "cos", EOpCos); + symbolTable.relateToOperator(COMMON_BUILTINS, "tan", EOpTan); + symbolTable.relateToOperator(COMMON_BUILTINS, "asin", EOpAsin); + symbolTable.relateToOperator(COMMON_BUILTINS, "acos", EOpAcos); + symbolTable.relateToOperator(COMMON_BUILTINS, "atan", EOpAtan); + + symbolTable.relateToOperator(COMMON_BUILTINS, "pow", EOpPow); + symbolTable.relateToOperator(COMMON_BUILTINS, "exp2", EOpExp2); + symbolTable.relateToOperator(COMMON_BUILTINS, "log", EOpLog); + symbolTable.relateToOperator(COMMON_BUILTINS, "exp", EOpExp); + symbolTable.relateToOperator(COMMON_BUILTINS, "log2", EOpLog2); + symbolTable.relateToOperator(COMMON_BUILTINS, "sqrt", EOpSqrt); + symbolTable.relateToOperator(COMMON_BUILTINS, "inversesqrt", EOpInverseSqrt); + + symbolTable.relateToOperator(COMMON_BUILTINS, "abs", EOpAbs); + symbolTable.relateToOperator(COMMON_BUILTINS, "sign", EOpSign); + symbolTable.relateToOperator(COMMON_BUILTINS, "floor", EOpFloor); + symbolTable.relateToOperator(COMMON_BUILTINS, "ceil", EOpCeil); + symbolTable.relateToOperator(COMMON_BUILTINS, "fract", EOpFract); + symbolTable.relateToOperator(COMMON_BUILTINS, "mod", EOpMod); + symbolTable.relateToOperator(COMMON_BUILTINS, "min", EOpMin); + symbolTable.relateToOperator(COMMON_BUILTINS, "max", EOpMax); + symbolTable.relateToOperator(COMMON_BUILTINS, "clamp", EOpClamp); + symbolTable.relateToOperator(COMMON_BUILTINS, "mix", EOpMix); + symbolTable.relateToOperator(COMMON_BUILTINS, "step", EOpStep); + symbolTable.relateToOperator(COMMON_BUILTINS, "smoothstep", EOpSmoothStep); + + symbolTable.relateToOperator(COMMON_BUILTINS, "length", EOpLength); + symbolTable.relateToOperator(COMMON_BUILTINS, "distance", EOpDistance); + symbolTable.relateToOperator(COMMON_BUILTINS, "dot", EOpDot); + symbolTable.relateToOperator(COMMON_BUILTINS, "cross", EOpCross); + symbolTable.relateToOperator(COMMON_BUILTINS, "normalize", EOpNormalize); + symbolTable.relateToOperator(COMMON_BUILTINS, "faceforward", EOpFaceForward); + symbolTable.relateToOperator(COMMON_BUILTINS, "reflect", EOpReflect); + symbolTable.relateToOperator(COMMON_BUILTINS, "refract", EOpRefract); + + symbolTable.relateToOperator(COMMON_BUILTINS, "any", EOpAny); + symbolTable.relateToOperator(COMMON_BUILTINS, "all", EOpAll); + symbolTable.relateToOperator(COMMON_BUILTINS, "not", EOpVectorLogicalNot); + + // Map language-specific operators. + switch(type) { + case SH_VERTEX_SHADER: + break; + case SH_FRAGMENT_SHADER: + if (resources.OES_standard_derivatives) + { + symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdx", EOpDFdx); + symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdy", EOpDFdy); + symbolTable.relateToOperator(ESSL1_BUILTINS, "fwidth", EOpFwidth); + + symbolTable.relateToExtension(ESSL1_BUILTINS, "dFdx", "GL_OES_standard_derivatives"); + symbolTable.relateToExtension(ESSL1_BUILTINS, "dFdy", "GL_OES_standard_derivatives"); + symbolTable.relateToExtension(ESSL1_BUILTINS, "fwidth", "GL_OES_standard_derivatives"); + } + if (resources.EXT_shader_texture_lod) + { + symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DLodEXT", "GL_EXT_shader_texture_lod"); + symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjLodEXT", "GL_EXT_shader_texture_lod"); + symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeLodEXT", "GL_EXT_shader_texture_lod"); + } + break; + default: break; + } + + symbolTable.relateToOperator(ESSL3_BUILTINS, "dFdx", EOpDFdx); + symbolTable.relateToOperator(ESSL3_BUILTINS, "dFdy", EOpDFdy); + symbolTable.relateToOperator(ESSL3_BUILTINS, "fwidth", EOpFwidth); + + if (resources.EXT_shader_texture_lod) + { + symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DGradEXT", "GL_EXT_shader_texture_lod"); + symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjGradEXT", "GL_EXT_shader_texture_lod"); + symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeGradEXT", "GL_EXT_shader_texture_lod"); + } + + // Finally add resource-specific variables. + switch(type) { + case SH_FRAGMENT_SHADER: + if (spec != SH_CSS_SHADERS_SPEC) { + // Set up gl_FragData. The array size. + TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true); + fragData.setArraySize(resources.MaxDrawBuffers); + symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData)); + } + break; + default: break; + } +} + +void InitExtensionBehavior(const ShBuiltInResources& resources, + TExtensionBehavior& extBehavior) +{ + if (resources.OES_standard_derivatives) + extBehavior["GL_OES_standard_derivatives"] = EBhUndefined; + if (resources.OES_EGL_image_external) + extBehavior["GL_OES_EGL_image_external"] = EBhUndefined; + if (resources.ARB_texture_rectangle) + extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined; + if (resources.EXT_draw_buffers) + extBehavior["GL_EXT_draw_buffers"] = EBhUndefined; + if (resources.EXT_frag_depth) + extBehavior["GL_EXT_frag_depth"] = EBhUndefined; + if (resources.EXT_shader_texture_lod) + extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined; +} diff --git a/chromium/third_party/angle/src/compiler/Initialize.h b/chromium/third_party/angle/src/compiler/translator/Initialize.h index 4aa13466aca..b5642869aa1 100644 --- a/chromium/third_party/angle/src/compiler/Initialize.h +++ b/chromium/third_party/angle/src/compiler/translator/Initialize.h @@ -7,9 +7,9 @@ #ifndef _INITIALIZE_INCLUDED_ #define _INITIALIZE_INCLUDED_ -#include "compiler/Common.h" -#include "compiler/ShHandle.h" -#include "compiler/SymbolTable.h" +#include "compiler/translator/Common.h" +#include "compiler/translator/ShHandle.h" +#include "compiler/translator/SymbolTable.h" void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table); diff --git a/chromium/third_party/angle/src/compiler/InitializeDll.cpp b/chromium/third_party/angle/src/compiler/translator/InitializeDll.cpp index 6c7f27fced1..43f81784d0a 100644 --- a/chromium/third_party/angle/src/compiler/InitializeDll.cpp +++ b/chromium/third_party/angle/src/compiler/translator/InitializeDll.cpp @@ -4,11 +4,11 @@ // found in the LICENSE file. // -#include "compiler/InitializeDll.h" +#include "compiler/translator/InitializeDll.h" -#include "compiler/InitializeGlobals.h" -#include "compiler/InitializeParseContext.h" -#include "compiler/osinclude.h" +#include "compiler/translator/InitializeGlobals.h" +#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/osinclude.h" bool InitProcess() { diff --git a/chromium/third_party/angle/src/compiler/InitializeDll.h b/chromium/third_party/angle/src/compiler/translator/InitializeDll.h index 43070cc3ff7..43070cc3ff7 100644 --- a/chromium/third_party/angle/src/compiler/InitializeDll.h +++ b/chromium/third_party/angle/src/compiler/translator/InitializeDll.h diff --git a/chromium/third_party/angle/src/compiler/InitializeGlobals.h b/chromium/third_party/angle/src/compiler/translator/InitializeGlobals.h index 07159414247..07159414247 100644 --- a/chromium/third_party/angle/src/compiler/InitializeGlobals.h +++ b/chromium/third_party/angle/src/compiler/translator/InitializeGlobals.h diff --git a/chromium/third_party/angle/src/compiler/InitializeParseContext.cpp b/chromium/third_party/angle/src/compiler/translator/InitializeParseContext.cpp index dfab027330d..b4defae5695 100644 --- a/chromium/third_party/angle/src/compiler/InitializeParseContext.cpp +++ b/chromium/third_party/angle/src/compiler/translator/InitializeParseContext.cpp @@ -4,9 +4,9 @@ // found in the LICENSE file. // -#include "compiler/InitializeParseContext.h" +#include "compiler/translator/InitializeParseContext.h" -#include "compiler/osinclude.h" +#include "compiler/translator/osinclude.h" OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX; diff --git a/chromium/third_party/angle/src/compiler/InitializeParseContext.h b/chromium/third_party/angle/src/compiler/translator/InitializeParseContext.h index bffbab87d07..bffbab87d07 100644 --- a/chromium/third_party/angle/src/compiler/InitializeParseContext.h +++ b/chromium/third_party/angle/src/compiler/translator/InitializeParseContext.h diff --git a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp new file mode 100644 index 00000000000..115c561c775 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp @@ -0,0 +1,116 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/InitializeVariables.h" +#include "compiler/translator/compilerdebug.h" + +namespace +{ + +TIntermConstantUnion* constructFloatConstUnionNode(const TType& type) +{ + TType myType = type; + unsigned char size = myType.getNominalSize(); + if (myType.isMatrix()) + size *= size; + ConstantUnion *u = new ConstantUnion[size]; + for (int ii = 0; ii < size; ++ii) + u[ii].setFConst(0.0f); + + myType.clearArrayness(); + myType.setQualifier(EvqConst); + TIntermConstantUnion *node = new TIntermConstantUnion(u, myType); + return node; +} + +TIntermConstantUnion* constructIndexNode(int index) +{ + ConstantUnion *u = new ConstantUnion[1]; + u[0].setIConst(index); + + TType type(EbtInt, EbpUndefined, EvqConst, 1); + TIntermConstantUnion *node = new TIntermConstantUnion(u, type); + return node; +} + +} // namespace anonymous + +bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate* node) +{ + bool visitChildren = !mCodeInserted; + switch (node->getOp()) + { + case EOpSequence: + break; + case EOpFunction: + { + // Function definition. + ASSERT(visit == PreVisit); + if (node->getName() == "main(") + { + TIntermSequence &sequence = node->getSequence(); + ASSERT((sequence.size() == 1) || (sequence.size() == 2)); + TIntermAggregate *body = NULL; + if (sequence.size() == 1) + { + body = new TIntermAggregate(EOpSequence); + sequence.push_back(body); + } + else + { + body = sequence[1]->getAsAggregate(); + } + ASSERT(body); + insertInitCode(body->getSequence()); + mCodeInserted = true; + } + break; + } + default: + visitChildren = false; + break; + } + return visitChildren; +} + +void InitializeVariables::insertInitCode(TIntermSequence& sequence) +{ + for (size_t ii = 0; ii < mVariables.size(); ++ii) + { + const InitVariableInfo& varInfo = mVariables[ii]; + + if (varInfo.type.isArray()) + { + for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index) + { + TIntermBinary *assign = new TIntermBinary(EOpAssign); + sequence.insert(sequence.begin(), assign); + + TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); + TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); + indexDirect->setLeft(symbol); + TIntermConstantUnion *indexNode = constructIndexNode(index); + indexDirect->setRight(indexNode); + + assign->setLeft(indexDirect); + + TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); + assign->setRight(zeroConst); + } + } + else + { + TIntermBinary *assign = new TIntermBinary(EOpAssign); + sequence.insert(sequence.begin(), assign); + TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); + assign->setLeft(symbol); + TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); + assign->setRight(zeroConst); + } + + } +} + diff --git a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h new file mode 100644 index 00000000000..1cd6d7e1b51 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h @@ -0,0 +1,50 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_INITIALIZE_VARIABLES_H_ +#define COMPILER_INITIALIZE_VARIABLES_H_ + +#include "compiler/translator/intermediate.h" + +class InitializeVariables : public TIntermTraverser +{ + public: + struct InitVariableInfo + { + TString name; + TType type; + + InitVariableInfo(const TString& _name, const TType& _type) + : name(_name), + type(_type) + { + } + }; + typedef TVector<InitVariableInfo> InitVariableInfoList; + + InitializeVariables(const InitVariableInfoList& vars) + : mCodeInserted(false), + mVariables(vars) + { + } + + protected: + virtual bool visitBinary(Visit visit, TIntermBinary* node) { return false; } + virtual bool visitUnary(Visit visit, TIntermUnary* node) { return false; } + virtual bool visitSelection(Visit visit, TIntermSelection* node) { return false; } + virtual bool visitLoop(Visit visit, TIntermLoop* node) { return false; } + virtual bool visitBranch(Visit visit, TIntermBranch* node) { return false; } + + virtual bool visitAggregate(Visit visit, TIntermAggregate* node); + + private: + void insertInitCode(TIntermSequence& sequence); + + InitVariableInfoList mVariables; + bool mCodeInserted; +}; + +#endif // COMPILER_INITIALIZE_VARIABLES_H_ diff --git a/chromium/third_party/angle/src/compiler/IntermTraverse.cpp b/chromium/third_party/angle/src/compiler/translator/IntermTraverse.cpp index 9a691da71fd..69f87c32847 100644 --- a/chromium/third_party/angle/src/compiler/IntermTraverse.cpp +++ b/chromium/third_party/angle/src/compiler/translator/IntermTraverse.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" // // Traverse the intermediate representation tree, and @@ -45,7 +45,7 @@ void TIntermBinary::traverse(TIntermTraverser *it) // if (it->preVisit) visit = it->visitBinary(PreVisit, this); - + // // Visit the children, in the right order. // @@ -53,11 +53,11 @@ void TIntermBinary::traverse(TIntermTraverser *it) { it->incrementDepth(this); - if (it->rightToLeft) + if (it->rightToLeft) { if (right) right->traverse(it); - + if (it->inVisit) visit = it->visitBinary(InVisit, this); @@ -68,7 +68,7 @@ void TIntermBinary::traverse(TIntermTraverser *it) { if (left) left->traverse(it); - + if (it->inVisit) visit = it->visitBinary(InVisit, this); @@ -102,7 +102,7 @@ void TIntermUnary::traverse(TIntermTraverser *it) operand->traverse(it); it->decrementDepth(); } - + if (visit && it->postVisit) it->visitUnary(PostVisit, this); } @@ -113,10 +113,10 @@ void TIntermUnary::traverse(TIntermTraverser *it) void TIntermAggregate::traverse(TIntermTraverser *it) { bool visit = true; - + if (it->preVisit) visit = it->visitAggregate(PreVisit, this); - + if (visit) { it->incrementDepth(this); @@ -147,7 +147,7 @@ void TIntermAggregate::traverse(TIntermTraverser *it) } } } - + it->decrementDepth(); } @@ -164,7 +164,7 @@ void TIntermSelection::traverse(TIntermTraverser *it) if (it->preVisit) visit = it->visitSelection(PreVisit, this); - + if (visit) { it->incrementDepth(this); if (it->rightToLeft) { @@ -196,7 +196,7 @@ void TIntermLoop::traverse(TIntermTraverser *it) if (it->preVisit) visit = it->visitLoop(PreVisit, this); - + if (visit) { it->incrementDepth(this); @@ -246,7 +246,7 @@ void TIntermBranch::traverse(TIntermTraverser *it) if (it->preVisit) visit = it->visitBranch(PreVisit, this); - + if (visit && expression) { it->incrementDepth(this); expression->traverse(it); @@ -257,3 +257,7 @@ void TIntermBranch::traverse(TIntermTraverser *it) it->visitBranch(PostVisit, this); } +void TIntermRaw::traverse(TIntermTraverser *it) +{ + it->visitRaw(this); +} diff --git a/chromium/third_party/angle/src/compiler/Intermediate.cpp b/chromium/third_party/angle/src/compiler/translator/Intermediate.cpp index ef85821575a..9df2afc53c2 100644 --- a/chromium/third_party/angle/src/compiler/Intermediate.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Intermediate.cpp @@ -12,10 +12,11 @@ #include <limits.h> #include <algorithm> -#include "compiler/HashNames.h" -#include "compiler/localintermediate.h" -#include "compiler/QualifierAlive.h" -#include "compiler/RemoveTree.h" +#include "compiler/translator/HashNames.h" +#include "compiler/translator/localintermediate.h" +#include "compiler/translator/QualifierAlive.h" +#include "compiler/translator/RemoveTree.h" +#include "compiler/translator/SymbolTable.h" bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray); @@ -44,7 +45,8 @@ const char* getOperatorString(TOperator op) case EOpIndexDirect: case EOpIndexIndirect: return "[]"; - case EOpIndexDirectStruct: return "."; + case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: return "."; case EOpVectorSwizzle: return "."; case EOpAdd: return "+"; case EOpSub: return "-"; @@ -78,16 +80,24 @@ const char* getOperatorString(TOperator op) // Fall-through. case EOpConvIntToBool: + case EOpConvUIntToBool: case EOpConvFloatToBool: return "bool"; // Fall-through. case EOpConvBoolToFloat: + case EOpConvUIntToFloat: case EOpConvIntToFloat: return "float"; // Fall-through. case EOpConvFloatToInt: + case EOpConvUIntToInt: case EOpConvBoolToInt: return "int"; + // Fall-through. + case EOpConvIntToUInt: + case EOpConvFloatToUInt: + case EOpConvBoolToUInt: return "uint"; + case EOpRadians: return "radians"; case EOpDegrees: return "degrees"; case EOpSin: return "sin"; @@ -146,7 +156,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType // // Returns the added node. // -TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line, TSymbolTable& symbolTable) +TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line) { switch (op) { case EOpEqual: @@ -212,11 +222,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn // // See if we can fold constants. // - TIntermTyped* typedReturnNode = 0; TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); if (leftTempConstant && rightTempConstant) { - typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink); + TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink); if (typedReturnNode) return typedReturnNode; @@ -275,7 +284,7 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT // // Returns the added node. // -TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc& line, TSymbolTable& symbolTable) +TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc& line) { TIntermUnary* node; TIntermTyped* child = childNode->getAsTyped(); @@ -310,6 +319,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TBasicType newType = EbtVoid; switch (op) { case EOpConstructInt: newType = EbtInt; break; + case EOpConstructUInt: newType = EbtUInt; break; case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; default: break; @@ -318,7 +328,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, if (newType != EbtVoid) { child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary, child->getNominalSize(), - child->isMatrix(), + child->getSecondarySize(), child->isArray()), child); if (child == 0) @@ -330,6 +340,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, // switch (op) { case EOpConstructInt: + case EOpConstructUInt: case EOpConstructBool: case EOpConstructFloat: return child; @@ -411,12 +422,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt // // Does the base type allow operation? // - switch (node->getBasicType()) { - case EbtVoid: - case EbtSampler2D: - case EbtSamplerCube: - return 0; - default: break; + if (node->getBasicType() == EbtVoid || + IsSampler(node->getBasicType())) + { + return 0; } // @@ -452,6 +461,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpConstructInt: promoteTo = EbtInt; break; + case EOpConstructUInt: + promoteTo = EbtUInt; + break; default: // // implicit conversions were removed from the language. @@ -479,8 +491,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt switch (promoteTo) { case EbtFloat: switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToFloat; break; - case EbtBool: newOp = EOpConvBoolToFloat; break; + case EbtInt: newOp = EOpConvIntToFloat; break; + case EbtUInt: newOp = EOpConvFloatToUInt; break; + case EbtBool: newOp = EOpConvBoolToFloat; break; default: infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node"); return 0; @@ -488,8 +501,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt break; case EbtBool: switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToBool; break; - case EbtFloat: newOp = EOpConvFloatToBool; break; + case EbtInt: newOp = EOpConvIntToBool; break; + case EbtUInt: newOp = EOpConvBoolToUInt; break; + case EbtFloat: newOp = EOpConvFloatToBool; break; default: infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node"); return 0; @@ -497,6 +511,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt break; case EbtInt: switch (node->getBasicType()) { + case EbtUInt: newOp = EOpConvUIntToInt; break; case EbtBool: newOp = EOpConvBoolToInt; break; case EbtFloat: newOp = EOpConvFloatToInt; break; default: @@ -504,12 +519,22 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt return 0; } break; + case EbtUInt: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToUInt; break; + case EbtBool: newOp = EOpConvBoolToUInt; break; + case EbtFloat: newOp = EOpConvFloatToUInt; break; + default: + infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node"); + return 0; + } + break; default: infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion type"); return 0; } - TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray()); + TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getNominalSize(), node->getSecondarySize(), node->isArray()); newNode = new TIntermUnary(newOp, type); newNode->setLine(node->getLine()); newNode->setOperand(node); @@ -559,6 +584,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceL TIntermAggregate* aggNode = new TIntermAggregate; aggNode->getSequence().push_back(node); + aggNode->setLine(line); return aggNode; @@ -760,6 +786,26 @@ bool TIntermLoop::replaceChildNode( return false; } +void TIntermLoop::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const +{ + if (init) + { + nodeQueue->push(init); + } + if (cond) + { + nodeQueue->push(cond); + } + if (expr) + { + nodeQueue->push(expr); + } + if (body) + { + nodeQueue->push(body); + } +} + bool TIntermBranch::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -767,6 +813,14 @@ bool TIntermBranch::replaceChildNode( return false; } +void TIntermBranch::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const +{ + if (expression) + { + nodeQueue->push(expression); + } +} + bool TIntermBinary::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -775,6 +829,18 @@ bool TIntermBinary::replaceChildNode( return false; } +void TIntermBinary::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const +{ + if (left) + { + nodeQueue->push(left); + } + if (right) + { + nodeQueue->push(right); + } +} + bool TIntermUnary::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -782,6 +848,14 @@ bool TIntermUnary::replaceChildNode( return false; } +void TIntermUnary::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const +{ + if (operand) + { + nodeQueue->push(operand); + } +} + bool TIntermAggregate::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -792,6 +866,14 @@ bool TIntermAggregate::replaceChildNode( return false; } +void TIntermAggregate::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const +{ + for (size_t childIndex = 0; childIndex < sequence.size(); childIndex++) + { + nodeQueue->push(sequence[childIndex]); + } +} + bool TIntermSelection::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -801,6 +883,22 @@ bool TIntermSelection::replaceChildNode( return false; } +void TIntermSelection::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const +{ + if (condition) + { + nodeQueue->push(condition); + } + if (trueBlock) + { + nodeQueue->push(trueBlock); + } + if (falseBlock) + { + nodeQueue->push(falseBlock); + } +} + // // Say whether or not an operation node changes the value of a variable. // @@ -843,6 +941,10 @@ bool TIntermOperator::isConstructor() const case EOpConstructIVec3: case EOpConstructIVec4: case EOpConstructInt: + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructUInt: case EOpConstructBVec2: case EOpConstructBVec3: case EOpConstructBVec4: @@ -893,6 +995,36 @@ bool TIntermUnary::promote(TInfoSink&) return true; } +bool validateMultiplication(TOperator op, const TType &left, const TType &right) +{ + switch (op) + { + case EOpMul: + case EOpMulAssign: + return left.getNominalSize() == right.getNominalSize() && left.getSecondarySize() == right.getSecondarySize(); + case EOpVectorTimesScalar: + case EOpVectorTimesScalarAssign: + return true; + case EOpVectorTimesMatrix: + return left.getNominalSize() == right.getRows(); + case EOpVectorTimesMatrixAssign: + return left.getNominalSize() == right.getRows() && left.getNominalSize() == right.getCols(); + case EOpMatrixTimesVector: + return left.getCols() == right.getNominalSize(); + case EOpMatrixTimesScalar: + case EOpMatrixTimesScalarAssign: + return true; + case EOpMatrixTimesMatrix: + return left.getCols() == right.getRows(); + case EOpMatrixTimesMatrixAssign: + return left.getCols() == right.getCols() && left.getRows() == right.getRows(); + + default: + UNREACHABLE(); + return false; + } +} + // // Establishes the type of the resultant operation, as well as // makes the operator the correct one for the operands. @@ -902,7 +1034,8 @@ bool TIntermUnary::promote(TInfoSink&) bool TIntermBinary::promote(TInfoSink& infoSink) { // This function only handles scalars, vectors, and matrices. - if (left->isArray() || right->isArray()) { + if (left->isArray() || right->isArray()) + { infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operation for arrays"); return false; } @@ -924,17 +1057,20 @@ bool TIntermBinary::promote(TInfoSink& infoSink) // Binary operations results in temporary variables unless both // operands are const. - if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) { + if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) + { getTypePointer()->setQualifier(EvqTemporary); } - int size = std::max(left->getNominalSize(), right->getNominalSize()); + const int nominalSize = std::max(left->getNominalSize(), right->getNominalSize()); // - // All scalars. Code after this test assumes this case is removed! + // All scalars or structs. Code after this test assumes this case is removed! // - if (size == 1) { - switch (op) { + if (nominalSize == 1) + { + switch (op) + { // // Promote to conditional // @@ -954,7 +1090,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink) case EOpLogicalOr: // Both operands must be of type bool. if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool) + { return false; + } setType(TType(EbtBool, EbpUndefined)); break; @@ -966,80 +1104,118 @@ bool TIntermBinary::promote(TInfoSink& infoSink) // If we reach here, at least one of the operands is vector or matrix. // The other operand could be a scalar, vector, or matrix. - // Are the sizes compatible? - // - if (left->getNominalSize() != right->getNominalSize()) { - // If the nominal size of operands do not match: - // One of them must be scalar. - if (left->getNominalSize() != 1 && right->getNominalSize() != 1) - return false; - // Operator cannot be of type pure assignment. - if (op == EOpAssign || op == EOpInitialize) - return false; - } - - // // Can these two operands be combined? // TBasicType basicType = left->getBasicType(); - switch (op) { + switch (op) + { case EOpMul: - if (!left->isMatrix() && right->isMatrix()) { + if (!left->isMatrix() && right->isMatrix()) + { if (left->isVector()) + { op = EOpVectorTimesMatrix; - else { + setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), 1)); + } + else + { op = EOpMatrixTimesScalar; - setType(TType(basicType, higherPrecision, EvqTemporary, size, true)); + setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), right->getRows())); } - } else if (left->isMatrix() && !right->isMatrix()) { - if (right->isVector()) { + } + else if (left->isMatrix() && !right->isMatrix()) + { + if (right->isVector()) + { op = EOpMatrixTimesVector; - setType(TType(basicType, higherPrecision, EvqTemporary, size, false)); - } else { + setType(TType(basicType, higherPrecision, EvqTemporary, left->getRows(), 1)); + } + else + { op = EOpMatrixTimesScalar; } - } else if (left->isMatrix() && right->isMatrix()) { + } + else if (left->isMatrix() && right->isMatrix()) + { op = EOpMatrixTimesMatrix; - } else if (!left->isMatrix() && !right->isMatrix()) { - if (left->isVector() && right->isVector()) { + setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), left->getRows())); + } + else if (!left->isMatrix() && !right->isMatrix()) + { + if (left->isVector() && right->isVector()) + { // leave as component product - } else if (left->isVector() || right->isVector()) { + } + else if (left->isVector() || right->isVector()) + { op = EOpVectorTimesScalar; - setType(TType(basicType, higherPrecision, EvqTemporary, size, false)); + setType(TType(basicType, higherPrecision, EvqTemporary, nominalSize, 1)); } - } else { + } + else + { infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses"); return false; } + + if (!validateMultiplication(op, left->getType(), right->getType())) + { + return false; + } break; + case EOpMulAssign: - if (!left->isMatrix() && right->isMatrix()) { + if (!left->isMatrix() && right->isMatrix()) + { if (left->isVector()) + { op = EOpVectorTimesMatrixAssign; - else { + } + else + { return false; } - } else if (left->isMatrix() && !right->isMatrix()) { - if (right->isVector()) { + } + else if (left->isMatrix() && !right->isMatrix()) + { + if (right->isVector()) + { return false; - } else { + } + else + { op = EOpMatrixTimesScalarAssign; } - } else if (left->isMatrix() && right->isMatrix()) { + } + else if (left->isMatrix() && right->isMatrix()) + { op = EOpMatrixTimesMatrixAssign; - } else if (!left->isMatrix() && !right->isMatrix()) { - if (left->isVector() && right->isVector()) { + setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), left->getRows())); + } + else if (!left->isMatrix() && !right->isMatrix()) + { + if (left->isVector() && right->isVector()) + { // leave as component product - } else if (left->isVector() || right->isVector()) { + } + else if (left->isVector() || right->isVector()) + { if (! left->isVector()) return false; op = EOpVectorTimesScalarAssign; - setType(TType(basicType, higherPrecision, EvqTemporary, size, false)); + setType(TType(basicType, higherPrecision, EvqTemporary, left->getNominalSize(), 1)); } - } else { + } + else + { infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses"); return false; } + + if (!validateMultiplication(op, left->getType(), right->getType())) + { + return false; + } break; case EOpAssign: @@ -1050,10 +1226,28 @@ bool TIntermBinary::promote(TInfoSink& infoSink) case EOpAddAssign: case EOpSubAssign: case EOpDivAssign: - if ((left->isMatrix() && right->isVector()) || - (left->isVector() && right->isMatrix())) - return false; - setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix())); + { + if ((left->isMatrix() && right->isVector()) || + (left->isVector() && right->isMatrix())) + return false; + + // Are the sizes compatible? + if (left->getNominalSize() != right->getNominalSize() || left->getSecondarySize() != right->getSecondarySize()) + { + // If the nominal size of operands do not match: + // One of them must be scalar. + if (!left->isScalar() && !right->isScalar()) + return false; + + // Operator cannot be of type pure assignment. + if (op == EOpAssign || op == EOpInitialize) + return false; + } + + const int secondarySize = std::max(left->getSecondarySize(), right->getSecondarySize()); + + setType(TType(basicType, higherPrecision, EvqTemporary, nominalSize, secondarySize)); + } break; case EOpEqual: @@ -1062,8 +1256,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink) case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: - if ((left->isMatrix() && right->isVector()) || - (left->isVector() && right->isMatrix())) + if ((left->getNominalSize() != right->getNominalSize()) || + (left->getSecondarySize() != right->getSecondarySize())) return false; setType(TType(EbtBool, EbpUndefined)); break; @@ -1086,13 +1280,14 @@ bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, Co size_t size = fields[j]->type()->getObjectSize(); for (size_t i = 0; i < size; i++) { if (fields[j]->type()->getBasicType() == EbtStruct) { - if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index])) + if (!CompareStructure(*fields[j]->type(), &rightUnionArray[index], &leftUnionArray[index])) return false; } else { if (leftUnionArray[index] != rightUnionArray[index]) return false; index++; } + } } return true; @@ -1127,24 +1322,40 @@ bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink) { ConstantUnion *unionArray = getUnionArrayPointer(); + + if (!unionArray) + return 0; + size_t objectSize = getType().getObjectSize(); - if (constantNode) { // binary operations + if (constantNode) + { + // binary operations TIntermConstantUnion *node = constantNode->getAsConstantUnion(); ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); TType returnType = getType(); + if (!rightUnionArray) + return 0; + // for a case like float f = 1.2 + vec4(2,3,4,5); - if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) { + if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) + { rightUnionArray = new ConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; ++i) + { rightUnionArray[i] = *node->getUnionArrayPointer(); + } returnType = getType(); - } else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) { + } + else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) + { // for a case like float f = vec4(2,3,4,5) + 1.2; unionArray = new ConstantUnion[constantNode->getType().getObjectSize()]; for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i) + { unionArray[i] = *getUnionArrayPointer(); + } returnType = node->getType(); objectSize = constantNode->getType().getObjectSize(); } @@ -1154,261 +1365,357 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod bool boolNodeFlag = false; switch(op) { - case EOpAdd: - tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] + rightUnionArray[i]; - } - break; - case EOpSub: - tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] - rightUnionArray[i]; - } - break; + case EOpAdd: + tempConstArray = new ConstantUnion[objectSize]; + { + for (size_t i = 0; i < objectSize; i++) + tempConstArray[i] = unionArray[i] + rightUnionArray[i]; + } + break; + case EOpSub: + tempConstArray = new ConstantUnion[objectSize]; + { + for (size_t i = 0; i < objectSize; i++) + tempConstArray[i] = unionArray[i] - rightUnionArray[i]; + } + break; - case EOpMul: - case EOpVectorTimesScalar: - case EOpMatrixTimesScalar: - tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] * rightUnionArray[i]; - } - break; - case EOpMatrixTimesMatrix: - if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) { + case EOpMul: + case EOpVectorTimesScalar: + case EOpMatrixTimesScalar: + tempConstArray = new ConstantUnion[objectSize]; + { + for (size_t i = 0; i < objectSize; i++) + tempConstArray[i] = unionArray[i] * rightUnionArray[i]; + } + break; + + case EOpMatrixTimesMatrix: + { + if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) + { infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix multiply"); return 0; } - {// support MSVC++6.0 - int size = getNominalSize(); - tempConstArray = new ConstantUnion[size*size]; - for (int row = 0; row < size; row++) { - for (int column = 0; column < size; column++) { - tempConstArray[size * column + row].setFConst(0.0f); - for (int i = 0; i < size; i++) { - tempConstArray[size * column + row].setFConst(tempConstArray[size * column + row].getFConst() + unionArray[i * size + row].getFConst() * (rightUnionArray[column * size + i].getFConst())); - } + + const int leftCols = getCols(); + const int leftRows = getRows(); + const int rightCols = constantNode->getType().getCols(); + const int rightRows = constantNode->getType().getRows(); + const int resultCols = rightCols; + const int resultRows = leftRows; + + tempConstArray = new ConstantUnion[resultCols*resultRows]; + for (int row = 0; row < resultRows; row++) + { + for (int column = 0; column < resultCols; column++) + { + tempConstArray[resultRows * column + row].setFConst(0.0f); + for (int i = 0; i < leftCols; i++) + { + tempConstArray[resultRows * column + row].setFConst(tempConstArray[resultRows * column + row].getFConst() + unionArray[i * leftRows + row].getFConst() * (rightUnionArray[column * rightRows + i].getFConst())); } } } - break; - case EOpDiv: + + // update return type for matrix product + returnType.setPrimarySize(resultCols); + returnType.setSecondarySize(resultRows); + } + break; + + case EOpDiv: + { tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) { - switch (getType().getBasicType()) { - case EbtFloat: - if (rightUnionArray[i] == 0.0f) { - infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding"); - tempConstArray[i].setFConst(unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); - } else - tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst()); - break; + for (size_t i = 0; i < objectSize; i++) + { + switch (getType().getBasicType()) + { + case EbtFloat: + if (rightUnionArray[i] == 0.0f) + { + infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding"); + tempConstArray[i].setFConst(unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); + } + else + { + tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst()); + } + break; - case EbtInt: - if (rightUnionArray[i] == 0) { - infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding"); - tempConstArray[i].setIConst(INT_MAX); - } else - tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst()); - break; - default: - infoSink.info.message(EPrefixInternalError, getLine(), "Constant folding cannot be done for \"/\""); - return 0; + case EbtInt: + if (rightUnionArray[i] == 0) + { + infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding"); + tempConstArray[i].setIConst(INT_MAX); + } + else + { + tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst()); } + break; + + case EbtUInt: + if (rightUnionArray[i] == 0) + { + infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding"); + tempConstArray[i].setUConst(UINT_MAX); + } + else + { + tempConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst()); + } + break; + + default: + infoSink.info.message(EPrefixInternalError, getLine(), "Constant folding cannot be done for \"/\""); + return 0; } } - break; + } + break; - case EOpMatrixTimesVector: - if (node->getBasicType() != EbtFloat) { + case EOpMatrixTimesVector: + { + if (node->getBasicType() != EbtFloat) + { infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix times vector"); return 0; } - tempConstArray = new ConstantUnion[getNominalSize()]; - {// support MSVC++6.0 - for (int size = getNominalSize(), i = 0; i < size; i++) { - tempConstArray[i].setFConst(0.0f); - for (int j = 0; j < size; j++) { - tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst())); - } + const int matrixCols = getCols(); + const int matrixRows = getRows(); + + tempConstArray = new ConstantUnion[matrixRows]; + + for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) + { + tempConstArray[matrixRow].setFConst(0.0f); + for (int col = 0; col < matrixCols; col++) + { + tempConstArray[matrixRow].setFConst(tempConstArray[matrixRow].getFConst() + ((unionArray[col * matrixRows + matrixRow].getFConst()) * rightUnionArray[col].getFConst())); } } - tempNode = new TIntermConstantUnion(tempConstArray, node->getType()); + returnType = node->getType(); + returnType.setPrimarySize(matrixRows); + + tempNode = new TIntermConstantUnion(tempConstArray, returnType); tempNode->setLine(getLine()); return tempNode; + } - case EOpVectorTimesMatrix: - if (getType().getBasicType() != EbtFloat) { + case EOpVectorTimesMatrix: + { + if (getType().getBasicType() != EbtFloat) + { infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for vector times matrix"); return 0; } - tempConstArray = new ConstantUnion[getNominalSize()]; - {// support MSVC++6.0 - for (int size = getNominalSize(), i = 0; i < size; i++) { - tempConstArray[i].setFConst(0.0f); - for (int j = 0; j < size; j++) { - tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst())); - } + const int matrixCols = constantNode->getType().getCols(); + const int matrixRows = constantNode->getType().getRows(); + + tempConstArray = new ConstantUnion[matrixCols]; + + for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++) + { + tempConstArray[matrixCol].setFConst(0.0f); + for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) + { + tempConstArray[matrixCol].setFConst(tempConstArray[matrixCol].getFConst() + ((unionArray[matrixRow].getFConst()) * rightUnionArray[matrixCol * matrixRows + matrixRow].getFConst())); } } - break; - case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently + returnType.setPrimarySize(matrixCols); + } + break; + + case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently + { tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] && rightUnionArray[i]; + for (size_t i = 0; i < objectSize; i++) + { + tempConstArray[i] = unionArray[i] && rightUnionArray[i]; } - break; + } + break; - case EOpLogicalOr: // this code is written for possible future use, will not get executed currently + case EOpLogicalOr: // this code is written for possible future use, will not get executed currently + { tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] || rightUnionArray[i]; + for (size_t i = 0; i < objectSize; i++) + { + tempConstArray[i] = unionArray[i] || rightUnionArray[i]; } - break; + } + break; - case EOpLogicalXor: + case EOpLogicalXor: + { tempConstArray = new ConstantUnion[objectSize]; - {// support MSVC++6.0 - for (size_t i = 0; i < objectSize; i++) - switch (getType().getBasicType()) { - case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break; - default: assert(false && "Default missing"); + for (size_t i = 0; i < objectSize; i++) + { + switch (getType().getBasicType()) + { + case EbtBool: + tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); + break; + default: + UNREACHABLE(); + break; } } - break; + } + break; - case EOpLessThan: + case EOpLessThan: + assert(objectSize == 1); + tempConstArray = new ConstantUnion[1]; + tempConstArray->setBConst(*unionArray < *rightUnionArray); + returnType = TType(EbtBool, EbpUndefined, EvqConst); + break; + + case EOpGreaterThan: + assert(objectSize == 1); + tempConstArray = new ConstantUnion[1]; + tempConstArray->setBConst(*unionArray > *rightUnionArray); + returnType = TType(EbtBool, EbpUndefined, EvqConst); + break; + + case EOpLessThanEqual: + { assert(objectSize == 1); + ConstantUnion constant; + constant.setBConst(*unionArray > *rightUnionArray); tempConstArray = new ConstantUnion[1]; - tempConstArray->setBConst(*unionArray < *rightUnionArray); + tempConstArray->setBConst(!constant.getBConst()); returnType = TType(EbtBool, EbpUndefined, EvqConst); break; - case EOpGreaterThan: + } + + case EOpGreaterThanEqual: + { assert(objectSize == 1); + ConstantUnion constant; + constant.setBConst(*unionArray < *rightUnionArray); tempConstArray = new ConstantUnion[1]; - tempConstArray->setBConst(*unionArray > *rightUnionArray); + tempConstArray->setBConst(!constant.getBConst()); returnType = TType(EbtBool, EbpUndefined, EvqConst); break; - case EOpLessThanEqual: - { - assert(objectSize == 1); - ConstantUnion constant; - constant.setBConst(*unionArray > *rightUnionArray); - tempConstArray = new ConstantUnion[1]; - tempConstArray->setBConst(!constant.getBConst()); - returnType = TType(EbtBool, EbpUndefined, EvqConst); - break; - } - case EOpGreaterThanEqual: - { - assert(objectSize == 1); - ConstantUnion constant; - constant.setBConst(*unionArray < *rightUnionArray); - tempConstArray = new ConstantUnion[1]; - tempConstArray->setBConst(!constant.getBConst()); - returnType = TType(EbtBool, EbpUndefined, EvqConst); - break; - } + } - case EOpEqual: - if (getType().getBasicType() == EbtStruct) { - if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray)) + case EOpEqual: + if (getType().getBasicType() == EbtStruct) + { + if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray)) + boolNodeFlag = true; + } + else + { + for (size_t i = 0; i < objectSize; i++) + { + if (unionArray[i] != rightUnionArray[i]) + { boolNodeFlag = true; - } else { - for (size_t i = 0; i < objectSize; i++) { - if (unionArray[i] != rightUnionArray[i]) { - boolNodeFlag = true; - break; // break out of for loop - } + break; // break out of for loop } } + } - tempConstArray = new ConstantUnion[1]; - if (!boolNodeFlag) { - tempConstArray->setBConst(true); - } - else { - tempConstArray->setBConst(false); - } + tempConstArray = new ConstantUnion[1]; + if (!boolNodeFlag) + { + tempConstArray->setBConst(true); + } + else + { + tempConstArray->setBConst(false); + } - tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst)); - tempNode->setLine(getLine()); + tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst)); + tempNode->setLine(getLine()); - return tempNode; + return tempNode; - case EOpNotEqual: - if (getType().getBasicType() == EbtStruct) { - if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray)) + case EOpNotEqual: + if (getType().getBasicType() == EbtStruct) + { + if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray)) + boolNodeFlag = true; + } + else + { + for (size_t i = 0; i < objectSize; i++) + { + if (unionArray[i] == rightUnionArray[i]) + { boolNodeFlag = true; - } else { - for (size_t i = 0; i < objectSize; i++) { - if (unionArray[i] == rightUnionArray[i]) { - boolNodeFlag = true; - break; // break out of for loop - } + break; // break out of for loop } } + } - tempConstArray = new ConstantUnion[1]; - if (!boolNodeFlag) { - tempConstArray->setBConst(true); - } - else { - tempConstArray->setBConst(false); - } + tempConstArray = new ConstantUnion[1]; + if (!boolNodeFlag) + { + tempConstArray->setBConst(true); + } + else + { + tempConstArray->setBConst(false); + } - tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst)); - tempNode->setLine(getLine()); + tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst)); + tempNode->setLine(getLine()); - return tempNode; + return tempNode; - default: - infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operator for constant folding"); - return 0; + default: + infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operator for constant folding"); + return 0; } tempNode = new TIntermConstantUnion(tempConstArray, returnType); tempNode->setLine(getLine()); return tempNode; - } else { + } + else + { // // Do unary operations // TIntermConstantUnion *newNode = 0; ConstantUnion* tempConstArray = new ConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) { - switch(op) { - case EOpNegative: - switch (getType().getBasicType()) { - case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break; - case EbtInt: tempConstArray[i].setIConst(-unionArray[i].getIConst()); break; - default: - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return 0; - } - break; - case EOpLogicalNot: // this code is written for possible future use, will not get executed currently - switch (getType().getBasicType()) { - case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break; - default: - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return 0; - } - break; - default: + for (size_t i = 0; i < objectSize; i++) + { + switch(op) + { + case EOpNegative: + switch (getType().getBasicType()) + { + case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break; + case EbtInt: tempConstArray[i].setIConst(-unionArray[i].getIConst()); break; + case EbtUInt: tempConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break; + default: + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); return 0; + } + break; + + case EOpLogicalNot: // this code is written for possible future use, will not get executed currently + switch (getType().getBasicType()) + { + case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break; + default: + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return 0; + } + break; + + default: + return 0; } } newNode = new TIntermConstantUnion(tempConstArray, getType()); @@ -1423,7 +1730,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ConstantUnion *leftUnionArray = new ConstantUnion[size]; - for (size_t i = 0; i < size; i++) { + for (size_t i=0; i < size; i++) { switch (promoteTo) { case EbtFloat: @@ -1431,6 +1738,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC case EbtInt: leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i))); break; + case EbtUInt: + leftUnionArray[i].setFConst(static_cast<float>(node->getUConst(i))); + break; case EbtBool: leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i))); break; @@ -1447,6 +1757,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC case EbtInt: leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i))); break; + case EbtUInt: + leftUnionArray[i].setIConst(static_cast<int>(node->getUConst(i))); + break; case EbtBool: leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i))); break; @@ -1458,11 +1771,33 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC return 0; } break; + case EbtUInt: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getIConst(i))); + break; + case EbtUInt: + leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getUConst(i))); + break; + case EbtBool: + leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getBConst(i))); + break; + case EbtFloat: + leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getFConst(i))); + break; + default: + infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote"); + return 0; + } + break; case EbtBool: switch (node->getType().getBasicType()) { case EbtInt: leftUnionArray[i].setBConst(node->getIConst(i) != 0); break; + case EbtUInt: + leftUnionArray[i].setBConst(node->getUConst(i) != 0); + break; case EbtBool: leftUnionArray[i].setBConst(node->getBConst(i)); break; @@ -1484,7 +1819,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC const TType& t = node->getType(); - return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine()); + return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.getSecondarySize(), t.isArray()), node->getLine()); } // static diff --git a/chromium/third_party/angle/src/compiler/translator/LoopInfo.cpp b/chromium/third_party/angle/src/compiler/translator/LoopInfo.cpp new file mode 100644 index 00000000000..226f1b23807 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/LoopInfo.cpp @@ -0,0 +1,211 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/LoopInfo.h" + +namespace +{ + +int EvaluateIntConstant(TIntermConstantUnion *node) +{ + ASSERT(node && node->getUnionArrayPointer()); + return node->getIConst(0); +} + +int GetLoopIntIncrement(TIntermLoop *node) +{ + TIntermNode *expr = node->getExpression(); + // for expression has one of the following forms: + // loop_index++ + // loop_index-- + // loop_index += constant_expression + // loop_index -= constant_expression + // ++loop_index + // --loop_index + // The last two forms are not specified in the spec, but I am assuming + // its an oversight. + TIntermUnary *unOp = expr->getAsUnaryNode(); + TIntermBinary *binOp = unOp ? NULL : expr->getAsBinaryNode(); + + TOperator op = EOpNull; + TIntermConstantUnion *incrementNode = NULL; + if (unOp) + { + op = unOp->getOp(); + } + else if (binOp) + { + op = binOp->getOp(); + ASSERT(binOp->getRight()); + incrementNode = binOp->getRight()->getAsConstantUnion(); + ASSERT(incrementNode); + } + + int increment = 0; + // The operator is one of: ++ -- += -=. + switch (op) + { + case EOpPostIncrement: + case EOpPreIncrement: + ASSERT(unOp && !binOp); + increment = 1; + break; + case EOpPostDecrement: + case EOpPreDecrement: + ASSERT(unOp && !binOp); + increment = -1; + break; + case EOpAddAssign: + ASSERT(!unOp && binOp); + increment = EvaluateIntConstant(incrementNode); + break; + case EOpSubAssign: + ASSERT(!unOp && binOp); + increment = - EvaluateIntConstant(incrementNode); + break; + default: + UNREACHABLE(); + } + + return increment; +} + +} // namespace anonymous + +TLoopIndexInfo::TLoopIndexInfo() + : mId(-1), + mType(EbtVoid), + mInitValue(0), + mStopValue(0), + mIncrementValue(0), + mOp(EOpNull), + mCurrentValue(0) +{ +} + +void TLoopIndexInfo::fillInfo(TIntermLoop *node) +{ + if (node == NULL) + return; + + // Here we assume all the operations are valid, because the loop node is + // already validated in ValidateLimitations. + TIntermSequence &declSeq = + node->getInit()->getAsAggregate()->getSequence(); + TIntermBinary *declInit = declSeq[0]->getAsBinaryNode(); + TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode(); + + mId = symbol->getId(); + mType = symbol->getBasicType(); + + if (mType == EbtInt) + { + TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion(); + mInitValue = EvaluateIntConstant(initNode); + mCurrentValue = mInitValue; + mIncrementValue = GetLoopIntIncrement(node); + + TIntermBinary* binOp = node->getCondition()->getAsBinaryNode(); + mStopValue = EvaluateIntConstant( + binOp->getRight()->getAsConstantUnion()); + mOp = binOp->getOp(); + } +} + +bool TLoopIndexInfo::satisfiesLoopCondition() const +{ + // Relational operator is one of: > >= < <= == or !=. + switch (mOp) + { + case EOpEqual: + return (mCurrentValue == mStopValue); + case EOpNotEqual: + return (mCurrentValue != mStopValue); + case EOpLessThan: + return (mCurrentValue < mStopValue); + case EOpGreaterThan: + return (mCurrentValue > mStopValue); + case EOpLessThanEqual: + return (mCurrentValue <= mStopValue); + case EOpGreaterThanEqual: + return (mCurrentValue >= mStopValue); + default: + UNREACHABLE(); + return false; + } +} + +TLoopInfo::TLoopInfo() + : loop(NULL) +{ +} + +TLoopInfo::TLoopInfo(TIntermLoop *node) + : loop(node) +{ + index.fillInfo(node); +} + +TIntermLoop *TLoopStack::findLoop(TIntermSymbol *symbol) +{ + if (!symbol) + return NULL; + for (iterator iter = begin(); iter != end(); ++iter) + { + if (iter->index.getId() == symbol->getId()) + return iter->loop; + } + return NULL; +} + +TLoopIndexInfo *TLoopStack::getIndexInfo(TIntermSymbol *symbol) +{ + if (!symbol) + return NULL; + for (iterator iter = begin(); iter != end(); ++iter) + { + if (iter->index.getId() == symbol->getId()) + return &(iter->index); + } + return NULL; +} + +void TLoopStack::step() +{ + ASSERT(!empty()); + rbegin()->index.step(); +} + +bool TLoopStack::satisfiesLoopCondition() +{ + ASSERT(!empty()); + return rbegin()->index.satisfiesLoopCondition(); +} + +bool TLoopStack::needsToReplaceSymbolWithValue(TIntermSymbol *symbol) +{ + TIntermLoop *loop = findLoop(symbol); + return loop && loop->getUnrollFlag(); +} + +int TLoopStack::getLoopIndexValue(TIntermSymbol *symbol) +{ + TLoopIndexInfo *info = getIndexInfo(symbol); + ASSERT(info); + return info->getCurrentValue(); +} + +void TLoopStack::push(TIntermLoop *loop) +{ + TLoopInfo info(loop); + push_back(info); +} + +void TLoopStack::pop() +{ + pop_back(); +} + diff --git a/chromium/third_party/angle/src/compiler/translator/LoopInfo.h b/chromium/third_party/angle/src/compiler/translator/LoopInfo.h new file mode 100644 index 00000000000..5a140c339e9 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/LoopInfo.h @@ -0,0 +1,80 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATOR_LOOP_INFO_H_ +#define COMPILER_TRANSLATOR_LOOP_INFO_H_ + +#include "compiler/translator/intermediate.h" + +class TLoopIndexInfo +{ + public: + TLoopIndexInfo(); + + // If type is EbtInt, fill all fields of the structure with info + // extracted from a loop node. + // If type is not EbtInt, only fill id and type. + void fillInfo(TIntermLoop *node); + + int getId() const { return mId; } + void setId(int id) { mId = id; } + TBasicType getType() const { return mType; } + void setType(TBasicType type) { mType = type; } + int getCurrentValue() const { return mCurrentValue; } + + void step() { mCurrentValue += mIncrementValue; } + + // Check if the current value satisfies the loop condition. + bool satisfiesLoopCondition() const; + + private: + int mId; + TBasicType mType; // Either EbtInt or EbtFloat + + // Below fields are only valid if the index's type is int. + int mInitValue; + int mStopValue; + int mIncrementValue; + TOperator mOp; + int mCurrentValue; +}; + +struct TLoopInfo +{ + TLoopIndexInfo index; + TIntermLoop *loop; + + TLoopInfo(); + TLoopInfo(TIntermLoop *node); +}; + +class TLoopStack : public TVector<TLoopInfo> +{ + public: + // Search loop stack for a loop whose index matches the input symbol. + TIntermLoop *findLoop(TIntermSymbol *symbol); + + // Find the loop index info in the loop stack by the input symbol. + TLoopIndexInfo *getIndexInfo(TIntermSymbol *symbol); + + // Update the currentValue for the next loop iteration. + void step(); + + // Return false if loop condition is no longer satisfied. + bool satisfiesLoopCondition(); + + // Check if the symbol is the index of a loop that's unrolled. + bool needsToReplaceSymbolWithValue(TIntermSymbol *symbol); + + // Return the current value of a given loop index symbol. + int getLoopIndexValue(TIntermSymbol *symbol); + + void push(TIntermLoop *info); + void pop(); +}; + +#endif // COMPILER_TRANSLATOR_LOOP_INDEX_H_ + diff --git a/chromium/third_party/angle/src/compiler/MMap.h b/chromium/third_party/angle/src/compiler/translator/MMap.h index a308671514c..a308671514c 100644 --- a/chromium/third_party/angle/src/compiler/MMap.h +++ b/chromium/third_party/angle/src/compiler/translator/MMap.h diff --git a/chromium/third_party/angle/src/compiler/NodeSearch.h b/chromium/third_party/angle/src/compiler/translator/NodeSearch.h index 27e471dbbc4..b58c7ec6894 100644 --- a/chromium/third_party/angle/src/compiler/NodeSearch.h +++ b/chromium/third_party/angle/src/compiler/translator/NodeSearch.h @@ -9,6 +9,8 @@ #ifndef TRANSLATOR_NODESEARCH_H_ #define TRANSLATOR_NODESEARCH_H_ +#include "compiler/translator/intermediate.h" + namespace sh { diff --git a/chromium/third_party/angle/src/compiler/OutputESSL.cpp b/chromium/third_party/angle/src/compiler/translator/OutputESSL.cpp index c2048f1cec4..65635af1fff 100644 --- a/chromium/third_party/angle/src/compiler/OutputESSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/OutputESSL.cpp @@ -1,17 +1,18 @@ // -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/OutputESSL.h" +#include "compiler/translator/OutputESSL.h" TOutputESSL::TOutputESSL(TInfoSinkBase& objSink, ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, NameMap& nameMap, - TSymbolTable& symbolTable) - : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable) + TSymbolTable& symbolTable, + int shaderVersion) + : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, shaderVersion) { } diff --git a/chromium/third_party/angle/src/compiler/OutputESSL.h b/chromium/third_party/angle/src/compiler/translator/OutputESSL.h index 05db96e4979..8a567fb8aa2 100644 --- a/chromium/third_party/angle/src/compiler/OutputESSL.h +++ b/chromium/third_party/angle/src/compiler/translator/OutputESSL.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,7 +7,7 @@ #ifndef CROSSCOMPILERGLSL_OUTPUTESSL_H_ #define CROSSCOMPILERGLSL_OUTPUTESSL_H_ -#include "compiler/OutputGLSLBase.h" +#include "compiler/translator/OutputGLSLBase.h" class TOutputESSL : public TOutputGLSLBase { @@ -16,7 +16,8 @@ public: ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, NameMap& nameMap, - TSymbolTable& symbolTable); + TSymbolTable& symbolTable, + int shaderVersion); protected: virtual bool writeVariablePrecision(TPrecision precision); diff --git a/chromium/third_party/angle/src/compiler/translator/OutputGLSL.cpp b/chromium/third_party/angle/src/compiler/translator/OutputGLSL.cpp new file mode 100644 index 00000000000..eb7cbb4ae86 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/OutputGLSL.cpp @@ -0,0 +1,57 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/OutputGLSL.h" + +TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink, + ShArrayIndexClampingStrategy clampingStrategy, + ShHashFunction64 hashFunction, + NameMap& nameMap, + TSymbolTable& symbolTable, + int shaderVersion) + : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, shaderVersion) +{ +} + +bool TOutputGLSL::writeVariablePrecision(TPrecision) +{ + return false; +} + +void TOutputGLSL::visitSymbol(TIntermSymbol* node) +{ + TInfoSinkBase& out = objSink(); + + if (node->getSymbol() == "gl_FragDepthEXT") + { + out << "gl_FragDepth"; + } + else + { + TOutputGLSLBase::visitSymbol(node); + } +} + +TString TOutputGLSL::translateTextureFunction(TString& name) +{ + static const char *simpleRename[] = { + "texture2DLodEXT", "texture2DLod", + "texture2DProjLodEXT", "texture2DProjLod", + "textureCubeLodEXT", "textureCubeLod", + "texture2DGradEXT", "texture2DGradARB", + "texture2DProjGradEXT", "texture2DProjGradARB", + "textureCubeGradEXT", "textureCubeGradARB", + NULL, NULL + }; + + for (int i = 0; simpleRename[i] != NULL; i += 2) { + if (name == simpleRename[i]) { + return simpleRename[i+1]; + } + } + + return name; +} diff --git a/chromium/third_party/angle/src/compiler/OutputGLSL.h b/chromium/third_party/angle/src/compiler/translator/OutputGLSL.h index fa68ac81030..bceebe397d7 100644 --- a/chromium/third_party/angle/src/compiler/OutputGLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/OutputGLSL.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,7 +7,7 @@ #ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_ #define CROSSCOMPILERGLSL_OUTPUTGLSL_H_ -#include "compiler/OutputGLSLBase.h" +#include "compiler/translator/OutputGLSLBase.h" class TOutputGLSL : public TOutputGLSLBase { @@ -16,11 +16,13 @@ public: ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, NameMap& nameMap, - TSymbolTable& symbolTable); + TSymbolTable& symbolTable, + int shaderVersion); protected: virtual bool writeVariablePrecision(TPrecision); virtual void visitSymbol(TIntermSymbol* node); + virtual TString translateTextureFunction(TString& name); }; #endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp new file mode 100644 index 00000000000..6995594e760 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp @@ -0,0 +1,1080 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/OutputGLSLBase.h" +#include "compiler/translator/compilerdebug.h" + +#include <cfloat> + +namespace +{ +TString arrayBrackets(const TType &type) +{ + ASSERT(type.isArray()); + TInfoSinkBase out; + out << "[" << type.getArraySize() << "]"; + return TString(out.c_str()); +} + +bool isSingleStatement(TIntermNode *node) +{ + if (const TIntermAggregate *aggregate = node->getAsAggregate()) + { + return (aggregate->getOp() != EOpFunction) && + (aggregate->getOp() != EOpSequence); + } + else if (const TIntermSelection *selection = node->getAsSelectionNode()) + { + // Ternary operators are usually part of an assignment operator. + // This handles those rare cases in which they are all by themselves. + return selection->usesTernaryOperator(); + } + else if (node->getAsLoopNode()) + { + return false; + } + return true; +} +} // namespace + +TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink, + ShArrayIndexClampingStrategy clampingStrategy, + ShHashFunction64 hashFunction, + NameMap &nameMap, + TSymbolTable &symbolTable, + int shaderVersion) + : TIntermTraverser(true, true, true), + mObjSink(objSink), + mDeclaringVariables(false), + mClampingStrategy(clampingStrategy), + mHashFunction(hashFunction), + mNameMap(nameMap), + mSymbolTable(symbolTable), + mShaderVersion(shaderVersion) +{ + // Set up global scope. + mDeclaredStructs.push_back(ScopedDeclaredStructs()); +} + +void TOutputGLSLBase::writeTriplet( + Visit visit, const char *preStr, const char *inStr, const char *postStr) +{ + TInfoSinkBase &out = objSink(); + if (visit == PreVisit && preStr) + out << preStr; + else if (visit == InVisit && inStr) + out << inStr; + else if (visit == PostVisit && postStr) + out << postStr; +} + +void TOutputGLSLBase::writeBuiltInFunctionTriplet( + Visit visit, const char *preStr, bool useEmulatedFunction) +{ + TString preString = useEmulatedFunction ? + BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr) : preStr; + writeTriplet(visit, preString.c_str(), ", ", ")"); +} + +void TOutputGLSLBase::writeVariableType(const TType &type) +{ + TInfoSinkBase &out = objSink(); + TQualifier qualifier = type.getQualifier(); + // TODO(alokp): Validate qualifier for variable declarations. + if (qualifier != EvqTemporary && qualifier != EvqGlobal) + out << type.getQualifierString() << " "; + // Declare the struct if we have not done so already. + if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct())) + { + declareStruct(type.getStruct()); + mDeclaredStructs[mDeclaredStructs.size() - 1].push_back(type.getStruct()); + } + else + { + if (writeVariablePrecision(type.getPrecision())) + out << " "; + out << getTypeName(type); + } +} + +void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args) +{ + TInfoSinkBase &out = objSink(); + for (TIntermSequence::const_iterator iter = args.begin(); + iter != args.end(); ++iter) + { + const TIntermSymbol *arg = (*iter)->getAsSymbolNode(); + ASSERT(arg != NULL); + + const TType &type = arg->getType(); + writeVariableType(type); + + const TString &name = arg->getSymbol(); + if (!name.empty()) + out << " " << hashName(name); + if (type.isArray()) + out << arrayBrackets(type); + + // Put a comma if this is not the last argument. + if (iter != args.end() - 1) + out << ", "; + } +} + +const ConstantUnion *TOutputGLSLBase::writeConstantUnion( + const TType &type, const ConstantUnion *pConstUnion) +{ + TInfoSinkBase &out = objSink(); + + if (type.getBasicType() == EbtStruct) + { + const TStructure *structure = type.getStruct(); + out << hashName(structure->name()) << "("; + + const TFieldList &fields = structure->fields(); + for (size_t i = 0; i < fields.size(); ++i) + { + const TType *fieldType = fields[i]->type(); + ASSERT(fieldType != NULL); + pConstUnion = writeConstantUnion(*fieldType, pConstUnion); + if (i != fields.size() - 1) + out << ", "; + } + out << ")"; + } + else + { + size_t size = type.getObjectSize(); + bool writeType = size > 1; + if (writeType) + out << getTypeName(type) << "("; + for (size_t i = 0; i < size; ++i, ++pConstUnion) + { + switch (pConstUnion->getType()) + { + case EbtFloat: + out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst())); + break; + case EbtInt: + out << pConstUnion->getIConst(); + break; + case EbtBool: + out << pConstUnion->getBConst(); + break; + default: UNREACHABLE(); + } + if (i != size - 1) + out << ", "; + } + if (writeType) + out << ")"; + } + return pConstUnion; +} + +void TOutputGLSLBase::visitSymbol(TIntermSymbol *node) +{ + TInfoSinkBase &out = objSink(); + if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node)) + out << mLoopUnrollStack.getLoopIndexValue(node); + else + out << hashVariableName(node->getSymbol()); + + if (mDeclaringVariables && node->getType().isArray()) + out << arrayBrackets(node->getType()); +} + +void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node) +{ + writeConstantUnion(node->getType(), node->getUnionArrayPointer()); +} + +bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) +{ + bool visitChildren = true; + TInfoSinkBase &out = objSink(); + switch (node->getOp()) + { + case EOpInitialize: + if (visit == InVisit) + { + out << " = "; + // RHS of initialize is not being declared. + mDeclaringVariables = false; + } + break; + case EOpAssign: + writeTriplet(visit, "(", " = ", ")"); + break; + case EOpAddAssign: + writeTriplet(visit, "(", " += ", ")"); + break; + case EOpSubAssign: + writeTriplet(visit, "(", " -= ", ")"); + break; + case EOpDivAssign: + writeTriplet(visit, "(", " /= ", ")"); + break; + // Notice the fall-through. + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + writeTriplet(visit, "(", " *= ", ")"); + break; + + case EOpIndexDirect: + writeTriplet(visit, NULL, "[", "]"); + break; + case EOpIndexIndirect: + if (node->getAddIndexClamp()) + { + if (visit == InVisit) + { + if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) + out << "[int(clamp(float("; + else + out << "[webgl_int_clamp("; + } + else if (visit == PostVisit) + { + int maxSize; + TIntermTyped *left = node->getLeft(); + TType leftType = left->getType(); + + if (left->isArray()) + { + // The shader will fail validation if the array length is not > 0. + maxSize = leftType.getArraySize() - 1; + } + else + { + maxSize = leftType.getNominalSize() - 1; + } + + if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) + out << "), 0.0, float(" << maxSize << ")))]"; + else + out << ", 0, " << maxSize << ")]"; + } + } + else + { + writeTriplet(visit, NULL, "[", "]"); + } + break; + case EOpIndexDirectStruct: + if (visit == InVisit) + { + // Here we are writing out "foo.bar", where "foo" is struct + // and "bar" is field. In AST, it is represented as a binary + // node, where left child represents "foo" and right child "bar". + // The node itself represents ".". The struct field "bar" is + // actually stored as an index into TStructure::fields. + out << "."; + const TStructure *structure = node->getLeft()->getType().getStruct(); + const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); + const TField *field = structure->fields()[index->getIConst(0)]; + + TString fieldName = field->name(); + if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion)) + fieldName = hashName(fieldName); + + out << fieldName; + visitChildren = false; + } + break; + case EOpVectorSwizzle: + if (visit == InVisit) + { + out << "."; + TIntermAggregate *rightChild = node->getRight()->getAsAggregate(); + TIntermSequence &sequence = rightChild->getSequence(); + for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit) + { + TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); + ASSERT(element->getBasicType() == EbtInt); + ASSERT(element->getNominalSize() == 1); + const ConstantUnion& data = element->getUnionArrayPointer()[0]; + ASSERT(data.getType() == EbtInt); + switch (data.getIConst()) + { + case 0: + out << "x"; + break; + case 1: + out << "y"; + break; + case 2: + out << "z"; + break; + case 3: + out << "w"; + break; + default: + UNREACHABLE(); + } + } + visitChildren = false; + } + break; + + case EOpAdd: + writeTriplet(visit, "(", " + ", ")"); + break; + case EOpSub: + writeTriplet(visit, "(", " - ", ")"); + break; + case EOpMul: + writeTriplet(visit, "(", " * ", ")"); + break; + case EOpDiv: + writeTriplet(visit, "(", " / ", ")"); + break; + case EOpMod: + UNIMPLEMENTED(); + break; + case EOpEqual: + writeTriplet(visit, "(", " == ", ")"); + break; + case EOpNotEqual: + writeTriplet(visit, "(", " != ", ")"); + break; + case EOpLessThan: + writeTriplet(visit, "(", " < ", ")"); + break; + case EOpGreaterThan: + writeTriplet(visit, "(", " > ", ")"); + break; + case EOpLessThanEqual: + writeTriplet(visit, "(", " <= ", ")"); + break; + case EOpGreaterThanEqual: + writeTriplet(visit, "(", " >= ", ")"); + break; + + // Notice the fall-through. + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpMatrixTimesMatrix: + writeTriplet(visit, "(", " * ", ")"); + break; + + case EOpLogicalOr: + writeTriplet(visit, "(", " || ", ")"); + break; + case EOpLogicalXor: + writeTriplet(visit, "(", " ^^ ", ")"); + break; + case EOpLogicalAnd: + writeTriplet(visit, "(", " && ", ")"); + break; + default: + UNREACHABLE(); + } + + return visitChildren; +} + +bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node) +{ + TString preString; + TString postString = ")"; + + switch (node->getOp()) + { + case EOpNegative: preString = "(-"; break; + case EOpVectorLogicalNot: preString = "not("; break; + case EOpLogicalNot: preString = "(!"; break; + + case EOpPostIncrement: preString = "("; postString = "++)"; break; + case EOpPostDecrement: preString = "("; postString = "--)"; break; + case EOpPreIncrement: preString = "(++"; break; + case EOpPreDecrement: preString = "(--"; break; + + case EOpConvIntToBool: + case EOpConvFloatToBool: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: + preString = "bool("; + break; + case 2: + preString = "bvec2("; + break; + case 3: + preString = "bvec3("; + break; + case 4: + preString = "bvec4("; + break; + default: + UNREACHABLE(); + } + break; + case EOpConvBoolToFloat: + case EOpConvIntToFloat: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: + preString = "float("; + break; + case 2: + preString = "vec2("; + break; + case 3: + preString = "vec3("; + break; + case 4: + preString = "vec4("; + break; + default: + UNREACHABLE(); + } + break; + case EOpConvFloatToInt: + case EOpConvBoolToInt: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: + preString = "int("; + break; + case 2: + preString = "ivec2("; + break; + case 3: + preString = "ivec3("; + break; + case 4: + preString = "ivec4("; + break; + default: + UNREACHABLE(); + } + break; + + case EOpRadians: + preString = "radians("; + break; + case EOpDegrees: + preString = "degrees("; + break; + case EOpSin: + preString = "sin("; + break; + case EOpCos: + preString = "cos("; + break; + case EOpTan: + preString = "tan("; + break; + case EOpAsin: + preString = "asin("; + break; + case EOpAcos: + preString = "acos("; + break; + case EOpAtan: + preString = "atan("; + break; + + case EOpExp: + preString = "exp("; + break; + case EOpLog: + preString = "log("; + break; + case EOpExp2: + preString = "exp2("; + break; + case EOpLog2: + preString = "log2("; + break; + case EOpSqrt: + preString = "sqrt("; + break; + case EOpInverseSqrt: + preString = "inversesqrt("; + break; + + case EOpAbs: + preString = "abs("; + break; + case EOpSign: + preString = "sign("; + break; + case EOpFloor: + preString = "floor("; + break; + case EOpCeil: + preString = "ceil("; + break; + case EOpFract: + preString = "fract("; + break; + + case EOpLength: + preString = "length("; + break; + case EOpNormalize: + preString = "normalize("; + break; + + case EOpDFdx: + preString = "dFdx("; + break; + case EOpDFdy: + preString = "dFdy("; + break; + case EOpFwidth: + preString = "fwidth("; + break; + + case EOpAny: + preString = "any("; + break; + case EOpAll: + preString = "all("; + break; + + default: + UNREACHABLE(); + } + + if (visit == PreVisit && node->getUseEmulatedFunction()) + preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); + writeTriplet(visit, preString.c_str(), NULL, postString.c_str()); + + return true; +} + +bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node) +{ + TInfoSinkBase &out = objSink(); + + if (node->usesTernaryOperator()) + { + // Notice two brackets at the beginning and end. The outer ones + // encapsulate the whole ternary expression. This preserves the + // order of precedence when ternary expressions are used in a + // compound expression, i.e., c = 2 * (a < b ? 1 : 2). + out << "(("; + node->getCondition()->traverse(this); + out << ") ? ("; + node->getTrueBlock()->traverse(this); + out << ") : ("; + node->getFalseBlock()->traverse(this); + out << "))"; + } + else + { + out << "if ("; + node->getCondition()->traverse(this); + out << ")\n"; + + incrementDepth(node); + visitCodeBlock(node->getTrueBlock()); + + if (node->getFalseBlock()) + { + out << "else\n"; + visitCodeBlock(node->getFalseBlock()); + } + decrementDepth(); + } + return false; +} + +bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) +{ + bool visitChildren = true; + TInfoSinkBase &out = objSink(); + TString preString; + bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction()); + switch (node->getOp()) + { + case EOpSequence: + // Scope the sequences except when at the global scope. + if (depth > 0) + { + out << "{\n"; + pushDeclaredStructsScope(); + } + + incrementDepth(node); + for (TIntermSequence::const_iterator iter = node->getSequence().begin(); + iter != node->getSequence().end(); ++iter) + { + TIntermNode *node = *iter; + ASSERT(node != NULL); + node->traverse(this); + + if (isSingleStatement(node)) + out << ";\n"; + } + decrementDepth(); + + // Scope the sequences except when at the global scope. + if (depth > 0) + { + popDeclaredStructsScope(); + out << "}\n"; + } + visitChildren = false; + break; + case EOpPrototype: + // Function declaration. + ASSERT(visit == PreVisit); + writeVariableType(node->getType()); + out << " " << hashName(node->getName()); + + out << "("; + writeFunctionParameters(node->getSequence()); + out << ")"; + + visitChildren = false; + break; + case EOpFunction: { + // Function definition. + ASSERT(visit == PreVisit); + writeVariableType(node->getType()); + out << " " << hashFunctionName(node->getName()); + + incrementDepth(node); + // Function definition node contains one or two children nodes + // representing function parameters and function body. The latter + // is not present in case of empty function bodies. + const TIntermSequence &sequence = node->getSequence(); + ASSERT((sequence.size() == 1) || (sequence.size() == 2)); + TIntermSequence::const_iterator seqIter = sequence.begin(); + + // Traverse function parameters. + TIntermAggregate *params = (*seqIter)->getAsAggregate(); + ASSERT(params != NULL); + ASSERT(params->getOp() == EOpParameters); + params->traverse(this); + + // Traverse function body. + TIntermAggregate *body = ++seqIter != sequence.end() ? + (*seqIter)->getAsAggregate() : NULL; + visitCodeBlock(body); + decrementDepth(); + + // Fully processed; no need to visit children. + visitChildren = false; + break; + } + case EOpFunctionCall: + // Function call. + if (visit == PreVisit) + out << hashFunctionName(node->getName()) << "("; + else if (visit == InVisit) + out << ", "; + else + out << ")"; + break; + case EOpParameters: + // Function parameters. + ASSERT(visit == PreVisit); + out << "("; + writeFunctionParameters(node->getSequence()); + out << ")"; + visitChildren = false; + break; + case EOpDeclaration: + // Variable declaration. + if (visit == PreVisit) + { + const TIntermSequence &sequence = node->getSequence(); + const TIntermTyped *variable = sequence.front()->getAsTyped(); + writeVariableType(variable->getType()); + out << " "; + mDeclaringVariables = true; + } + else if (visit == InVisit) + { + out << ", "; + mDeclaringVariables = true; + } + else + { + mDeclaringVariables = false; + } + break; + case EOpConstructFloat: + writeTriplet(visit, "float(", NULL, ")"); + break; + case EOpConstructVec2: + writeBuiltInFunctionTriplet(visit, "vec2(", false); + break; + case EOpConstructVec3: + writeBuiltInFunctionTriplet(visit, "vec3(", false); + break; + case EOpConstructVec4: + writeBuiltInFunctionTriplet(visit, "vec4(", false); + break; + case EOpConstructBool: + writeTriplet(visit, "bool(", NULL, ")"); + break; + case EOpConstructBVec2: + writeBuiltInFunctionTriplet(visit, "bvec2(", false); + break; + case EOpConstructBVec3: + writeBuiltInFunctionTriplet(visit, "bvec3(", false); + break; + case EOpConstructBVec4: + writeBuiltInFunctionTriplet(visit, "bvec4(", false); + break; + case EOpConstructInt: + writeTriplet(visit, "int(", NULL, ")"); + break; + case EOpConstructIVec2: + writeBuiltInFunctionTriplet(visit, "ivec2(", false); + break; + case EOpConstructIVec3: + writeBuiltInFunctionTriplet(visit, "ivec3(", false); + break; + case EOpConstructIVec4: + writeBuiltInFunctionTriplet(visit, "ivec4(", false); + break; + case EOpConstructMat2: + writeBuiltInFunctionTriplet(visit, "mat2(", false); + break; + case EOpConstructMat3: + writeBuiltInFunctionTriplet(visit, "mat3(", false); + break; + case EOpConstructMat4: + writeBuiltInFunctionTriplet(visit, "mat4(", false); + break; + case EOpConstructStruct: + if (visit == PreVisit) + { + const TType &type = node->getType(); + ASSERT(type.getBasicType() == EbtStruct); + out << hashName(type.getStruct()->name()) << "("; + } + else if (visit == InVisit) + { + out << ", "; + } + else + { + out << ")"; + } + break; + + case EOpLessThan: + writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction); + break; + case EOpGreaterThan: + writeBuiltInFunctionTriplet(visit, "greaterThan(", useEmulatedFunction); + break; + case EOpLessThanEqual: + writeBuiltInFunctionTriplet(visit, "lessThanEqual(", useEmulatedFunction); + break; + case EOpGreaterThanEqual: + writeBuiltInFunctionTriplet(visit, "greaterThanEqual(", useEmulatedFunction); + break; + case EOpVectorEqual: + writeBuiltInFunctionTriplet(visit, "equal(", useEmulatedFunction); + break; + case EOpVectorNotEqual: + writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction); + break; + case EOpComma: + writeTriplet(visit, NULL, ", ", NULL); + break; + + case EOpMod: + writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction); + break; + case EOpPow: + writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction); + break; + case EOpAtan: + writeBuiltInFunctionTriplet(visit, "atan(", useEmulatedFunction); + break; + case EOpMin: + writeBuiltInFunctionTriplet(visit, "min(", useEmulatedFunction); + break; + case EOpMax: + writeBuiltInFunctionTriplet(visit, "max(", useEmulatedFunction); + break; + case EOpClamp: + writeBuiltInFunctionTriplet(visit, "clamp(", useEmulatedFunction); + break; + case EOpMix: + writeBuiltInFunctionTriplet(visit, "mix(", useEmulatedFunction); + break; + case EOpStep: + writeBuiltInFunctionTriplet(visit, "step(", useEmulatedFunction); + break; + case EOpSmoothStep: + writeBuiltInFunctionTriplet(visit, "smoothstep(", useEmulatedFunction); + break; + case EOpDistance: + writeBuiltInFunctionTriplet(visit, "distance(", useEmulatedFunction); + break; + case EOpDot: + writeBuiltInFunctionTriplet(visit, "dot(", useEmulatedFunction); + break; + case EOpCross: + writeBuiltInFunctionTriplet(visit, "cross(", useEmulatedFunction); + break; + case EOpFaceForward: + writeBuiltInFunctionTriplet(visit, "faceforward(", useEmulatedFunction); + break; + case EOpReflect: + writeBuiltInFunctionTriplet(visit, "reflect(", useEmulatedFunction); + break; + case EOpRefract: + writeBuiltInFunctionTriplet(visit, "refract(", useEmulatedFunction); + break; + case EOpMul: + writeBuiltInFunctionTriplet(visit, "matrixCompMult(", useEmulatedFunction); + break; + + default: + UNREACHABLE(); + } + return visitChildren; +} + +bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) +{ + TInfoSinkBase &out = objSink(); + + incrementDepth(node); + // Loop header. + TLoopType loopType = node->getType(); + if (loopType == ELoopFor) // for loop + { + if (!node->getUnrollFlag()) + { + out << "for ("; + if (node->getInit()) + node->getInit()->traverse(this); + out << "; "; + + if (node->getCondition()) + node->getCondition()->traverse(this); + out << "; "; + + if (node->getExpression()) + node->getExpression()->traverse(this); + out << ")\n"; + } + else + { + // Need to put a one-iteration loop here to handle break. + TIntermSequence &declSeq = + node->getInit()->getAsAggregate()->getSequence(); + TIntermSymbol *indexSymbol = + declSeq[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); + TString name = hashVariableName(indexSymbol->getSymbol()); + out << "for (int " << name << " = 0; " + << name << " < 1; " + << "++" << name << ")\n"; + } + } + else if (loopType == ELoopWhile) // while loop + { + out << "while ("; + ASSERT(node->getCondition() != NULL); + node->getCondition()->traverse(this); + out << ")\n"; + } + else // do-while loop + { + ASSERT(loopType == ELoopDoWhile); + out << "do\n"; + } + + // Loop body. + if (node->getUnrollFlag()) + { + out << "{\n"; + mLoopUnrollStack.push(node); + while (mLoopUnrollStack.satisfiesLoopCondition()) + { + visitCodeBlock(node->getBody()); + mLoopUnrollStack.step(); + } + mLoopUnrollStack.pop(); + out << "}\n"; + } + else + { + visitCodeBlock(node->getBody()); + } + + // Loop footer. + if (loopType == ELoopDoWhile) // do-while loop + { + out << "while ("; + ASSERT(node->getCondition() != NULL); + node->getCondition()->traverse(this); + out << ");\n"; + } + decrementDepth(); + + // No need to visit children. They have been already processed in + // this function. + return false; +} + +bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node) +{ + switch (node->getFlowOp()) + { + case EOpKill: + writeTriplet(visit, "discard", NULL, NULL); + break; + case EOpBreak: + writeTriplet(visit, "break", NULL, NULL); + break; + case EOpContinue: + writeTriplet(visit, "continue", NULL, NULL); + break; + case EOpReturn: + writeTriplet(visit, "return ", NULL, NULL); + break; + default: + UNREACHABLE(); + } + + return true; +} + +void TOutputGLSLBase::visitCodeBlock(TIntermNode *node) +{ + TInfoSinkBase &out = objSink(); + if (node != NULL) + { + node->traverse(this); + // Single statements not part of a sequence need to be terminated + // with semi-colon. + if (isSingleStatement(node)) + out << ";\n"; + } + else + { + out << "{\n}\n"; // Empty code block. + } +} + +TString TOutputGLSLBase::getTypeName(const TType &type) +{ + TInfoSinkBase out; + if (type.isMatrix()) + { + out << "mat"; + out << type.getNominalSize(); + } + else if (type.isVector()) + { + switch (type.getBasicType()) + { + case EbtFloat: + out << "vec"; + break; + case EbtInt: + out << "ivec"; + break; + case EbtBool: + out << "bvec"; + break; + default: + UNREACHABLE(); + } + out << type.getNominalSize(); + } + else + { + if (type.getBasicType() == EbtStruct) + out << hashName(type.getStruct()->name()); + else + out << type.getBasicString(); + } + return TString(out.c_str()); +} + +TString TOutputGLSLBase::hashName(const TString &name) +{ + if (mHashFunction == NULL || name.empty()) + return name; + NameMap::const_iterator it = mNameMap.find(name.c_str()); + if (it != mNameMap.end()) + return it->second.c_str(); + TString hashedName = TIntermTraverser::hash(name, mHashFunction); + mNameMap[name.c_str()] = hashedName.c_str(); + return hashedName; +} + +TString TOutputGLSLBase::hashVariableName(const TString &name) +{ + if (mSymbolTable.findBuiltIn(name, mShaderVersion) != NULL) + return name; + return hashName(name); +} + +TString TOutputGLSLBase::hashFunctionName(const TString &mangled_name) +{ + TString name = TFunction::unmangleName(mangled_name); + if (mSymbolTable.findBuiltIn(mangled_name, mShaderVersion) != NULL || name == "main") + return translateTextureFunction(name); + return hashName(name); +} + +bool TOutputGLSLBase::structDeclared(const TStructure *structure) const +{ + ASSERT(structure); + ASSERT(mDeclaredStructs.size() > 0); + for (size_t ii = mDeclaredStructs.size(); ii > 0; --ii) + { + const ScopedDeclaredStructs &scope = mDeclaredStructs[ii - 1]; + for (size_t jj = 0; jj < scope.size(); ++jj) + { + if (scope[jj]->equals(*structure)) + return true; + } + } + return false; +} + +void TOutputGLSLBase::declareStruct(const TStructure *structure) +{ + TInfoSinkBase &out = objSink(); + + out << "struct " << hashName(structure->name()) << "{\n"; + const TFieldList &fields = structure->fields(); + for (size_t i = 0; i < fields.size(); ++i) + { + const TField *field = fields[i]; + if (writeVariablePrecision(field->type()->getPrecision())) + out << " "; + out << getTypeName(*field->type()) << " " << hashName(field->name()); + if (field->type()->isArray()) + out << arrayBrackets(*field->type()); + out << ";\n"; + } + out << "}"; +} + +void TOutputGLSLBase::pushDeclaredStructsScope() +{ + mDeclaredStructs.push_back(ScopedDeclaredStructs()); +} + +void TOutputGLSLBase::popDeclaredStructsScope() +{ + // We should never pop the global scope. + ASSERT(mDeclaredStructs.size() >= 2); + mDeclaredStructs.pop_back(); +} diff --git a/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h new file mode 100644 index 00000000000..ae40f85e0d5 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h @@ -0,0 +1,91 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ +#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ + +#include <vector> + +#include "compiler/translator/intermediate.h" +#include "compiler/translator/LoopInfo.h" +#include "compiler/translator/ParseContext.h" + +class TOutputGLSLBase : public TIntermTraverser +{ + public: + TOutputGLSLBase(TInfoSinkBase &objSink, + ShArrayIndexClampingStrategy clampingStrategy, + ShHashFunction64 hashFunction, + NameMap &nameMap, + TSymbolTable& symbolTable, + int shaderVersion); + + protected: + TInfoSinkBase &objSink() { return mObjSink; } + void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr); + void writeVariableType(const TType &type); + virtual bool writeVariablePrecision(TPrecision precision) = 0; + void writeFunctionParameters(const TIntermSequence &args); + const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *pConstUnion); + TString getTypeName(const TType &type); + + virtual void visitSymbol(TIntermSymbol *node); + virtual void visitConstantUnion(TIntermConstantUnion *node); + virtual bool visitBinary(Visit visit, TIntermBinary *node); + virtual bool visitUnary(Visit visit, TIntermUnary *node); + virtual bool visitSelection(Visit visit, TIntermSelection *node); + virtual bool visitAggregate(Visit visit, TIntermAggregate *node); + virtual bool visitLoop(Visit visit, TIntermLoop *node); + virtual bool visitBranch(Visit visit, TIntermBranch *node); + + void visitCodeBlock(TIntermNode *node); + + // Return the original name if hash function pointer is NULL; + // otherwise return the hashed name. + TString hashName(const TString &name); + // Same as hashName(), but without hashing built-in variables. + TString hashVariableName(const TString &name); + // Same as hashName(), but without hashing built-in functions. + TString hashFunctionName(const TString &mangled_name); + // Used to translate function names for differences between ESSL and GLSL + virtual TString translateTextureFunction(TString &name) { return name; } + + private: + bool structDeclared(const TStructure *structure) const; + void declareStruct(const TStructure *structure); + void pushDeclaredStructsScope(); + void popDeclaredStructsScope(); + + void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction); + + TInfoSinkBase &mObjSink; + bool mDeclaringVariables; + + // Structs are declared as the tree is traversed. This list contains all + // the structs already declared within a scope. It is maintained so that + // a struct is declared only once within a scope. + typedef std::vector<TStructure *> ScopedDeclaredStructs; + // This vector contains all the structs from the global scope to the + // current scope. When the traverser exits a scope, the scope is discarded. + typedef std::vector<ScopedDeclaredStructs> DeclaredStructs; + DeclaredStructs mDeclaredStructs; + + // Stack of loops that need to be unrolled. + TLoopStack mLoopUnrollStack; + + ShArrayIndexClampingStrategy mClampingStrategy; + + // name hashing. + ShHashFunction64 mHashFunction; + + NameMap &mNameMap; + + TSymbolTable &mSymbolTable; + + const int mShaderVersion; +}; + +#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp new file mode 100644 index 00000000000..5520c861b4d --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp @@ -0,0 +1,4184 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/OutputHLSL.h" + +#include "common/angleutils.h" +#include "common/utilities.h" +#include "common/blocklayout.h" +#include "compiler/translator/compilerdebug.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/DetectDiscontinuity.h" +#include "compiler/translator/SearchSymbol.h" +#include "compiler/translator/UnfoldShortCircuit.h" +#include "compiler/translator/FlagStd140Structs.h" +#include "compiler/translator/NodeSearch.h" +#include "compiler/translator/RewriteElseBlocks.h" + +#include <algorithm> +#include <cfloat> +#include <stdio.h> + +namespace sh +{ + +TString OutputHLSL::TextureFunction::name() const +{ + TString name = "gl_texture"; + + if (IsSampler2D(sampler)) + { + name += "2D"; + } + else if (IsSampler3D(sampler)) + { + name += "3D"; + } + else if (IsSamplerCube(sampler)) + { + name += "Cube"; + } + else UNREACHABLE(); + + if (proj) + { + name += "Proj"; + } + + if (offset) + { + name += "Offset"; + } + + switch(method) + { + case IMPLICIT: break; + case BIAS: break; // Extra parameter makes the signature unique + case LOD: name += "Lod"; break; + case LOD0: name += "Lod0"; break; + case LOD0BIAS: name += "Lod0"; break; // Extra parameter makes the signature unique + case SIZE: name += "Size"; break; + case FETCH: name += "Fetch"; break; + case GRAD: name += "Grad"; break; + default: UNREACHABLE(); + } + + return name + "("; +} + +const char *RegisterPrefix(const TType &type) +{ + if (IsSampler(type.getBasicType())) + { + return "s"; + } + else + { + return "c"; + } +} + +bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const +{ + if (sampler < rhs.sampler) return true; + if (sampler > rhs.sampler) return false; + + if (coords < rhs.coords) return true; + if (coords > rhs.coords) return false; + + if (!proj && rhs.proj) return true; + if (proj && !rhs.proj) return false; + + if (!offset && rhs.offset) return true; + if (offset && !rhs.offset) return false; + + if (method < rhs.method) return true; + if (method > rhs.method) return false; + + return false; +} + +OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType) + : TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType) +{ + mUnfoldShortCircuit = new UnfoldShortCircuit(context, this); + mInsideFunction = false; + + mUsesFragColor = false; + mUsesFragData = false; + mUsesDepthRange = false; + mUsesFragCoord = false; + mUsesPointCoord = false; + mUsesFrontFacing = false; + mUsesPointSize = false; + mUsesFragDepth = false; + mUsesXor = false; + mUsesMod1 = false; + mUsesMod2v = false; + mUsesMod2f = false; + mUsesMod3v = false; + mUsesMod3f = false; + mUsesMod4v = false; + mUsesMod4f = false; + mUsesFaceforward1 = false; + mUsesFaceforward2 = false; + mUsesFaceforward3 = false; + mUsesFaceforward4 = false; + mUsesAtan2_1 = false; + mUsesAtan2_2 = false; + mUsesAtan2_3 = false; + mUsesAtan2_4 = false; + mUsesDiscardRewriting = false; + mUsesNestedBreak = false; + + mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; + + mUniqueIndex = 0; + + mContainsLoopDiscontinuity = false; + mOutputLod0Function = false; + mInsideDiscontinuousLoop = false; + mNestedLoopDepth = 0; + + mExcessiveLoopIndex = NULL; + + if (mOutputType == SH_HLSL9_OUTPUT) + { + if (mContext.shaderType == SH_FRAGMENT_SHADER) + { + mUniformRegister = 3; // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront + } + else + { + mUniformRegister = 2; // Reserve registers for dx_DepthRange and dx_ViewAdjust + } + } + else + { + mUniformRegister = 0; + } + + mSamplerRegister = 0; + mInterfaceBlockRegister = 2; // Reserve registers for the default uniform block and driver constants + mPaddingCounter = 0; +} + +OutputHLSL::~OutputHLSL() +{ + delete mUnfoldShortCircuit; +} + +void OutputHLSL::output() +{ + mContainsLoopDiscontinuity = mContext.shaderType == SH_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot); + const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot); + makeFlaggedStructMaps(flaggedStructs); + + // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which + // use a vertex attribute as a condition, and some related computation in the else block. + if (mOutputType == SH_HLSL9_OUTPUT && mContext.shaderType == SH_VERTEX_SHADER) + { + RewriteElseBlocks(mContext.treeRoot); + } + + mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header + header(); + + mContext.infoSink().obj << mHeader.c_str(); + mContext.infoSink().obj << mBody.c_str(); +} + +void OutputHLSL::makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs) +{ + for (unsigned int structIndex = 0; structIndex < flaggedStructs.size(); structIndex++) + { + TIntermTyped *flaggedNode = flaggedStructs[structIndex]; + + // This will mark the necessary block elements as referenced + flaggedNode->traverse(this); + TString structName(mBody.c_str()); + mBody.erase(); + + mFlaggedStructOriginalNames[flaggedNode] = structName; + + for (size_t pos = structName.find('.'); pos != std::string::npos; pos = structName.find('.')) + { + structName.erase(pos, 1); + } + + mFlaggedStructMappedNames[flaggedNode] = "map" + structName; + } +} + +TInfoSinkBase &OutputHLSL::getBodyStream() +{ + return mBody; +} + +const std::vector<gl::Uniform> &OutputHLSL::getUniforms() +{ + return mActiveUniforms; +} + +const std::vector<gl::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const +{ + return mActiveInterfaceBlocks; +} + +const std::vector<gl::Attribute> &OutputHLSL::getOutputVariables() const +{ + return mActiveOutputVariables; +} + +const std::vector<gl::Attribute> &OutputHLSL::getAttributes() const +{ + return mActiveAttributes; +} + +const std::vector<gl::Varying> &OutputHLSL::getVaryings() const +{ + return mActiveVaryings; +} + +int OutputHLSL::vectorSize(const TType &type) const +{ + int elementSize = type.isMatrix() ? type.getCols() : 1; + int arraySize = type.isArray() ? type.getArraySize() : 1; + + return elementSize * arraySize; +} + +TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field) +{ + if (interfaceBlock.hasInstanceName()) + { + return interfaceBlock.name() + "." + field.name(); + } + else + { + return field.name(); + } +} + +TString OutputHLSL::decoratePrivate(const TString &privateText) +{ + return "dx_" + privateText; +} + +TString OutputHLSL::interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlock) +{ + return decoratePrivate(interfaceBlock.name()) + "_type"; +} + +TString OutputHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex) +{ + if (!interfaceBlock.hasInstanceName()) + { + return ""; + } + else if (interfaceBlock.isArray()) + { + return decoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex); + } + else + { + return decorate(interfaceBlock.instanceName()); + } +} + +TString OutputHLSL::interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage) +{ + const TType &fieldType = *field.type(); + const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking; + ASSERT(matrixPacking != EmpUnspecified); + + if (fieldType.isMatrix()) + { + // Use HLSL row-major packing for GLSL column-major matrices + const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major"); + return matrixPackString + " " + typeString(fieldType); + } + else if (fieldType.getStruct()) + { + // Use HLSL row-major packing for GLSL column-major matrices + return structureTypeName(*fieldType.getStruct(), matrixPacking == EmpColumnMajor, blockStorage == EbsStd140); + } + else + { + return typeString(fieldType); + } +} + +TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage) +{ + TString hlsl; + + int elementIndex = 0; + + for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++) + { + const TField &field = *interfaceBlock.fields()[typeIndex]; + const TType &fieldType = *field.type(); + + if (blockStorage == EbsStd140) + { + // 2 and 3 component vector types in some cases need pre-padding + hlsl += std140PrePaddingString(fieldType, &elementIndex); + } + + hlsl += " " + interfaceBlockFieldTypeString(field, blockStorage) + + " " + decorate(field.name()) + arrayString(fieldType) + ";\n"; + + // must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff + if (blockStorage == EbsStd140) + { + const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor); + hlsl += std140PostPaddingString(fieldType, useHLSLRowMajorPacking); + } + } + + return hlsl; +} + +TString OutputHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock) +{ + const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage(); + + return "struct " + interfaceBlockStructNameString(interfaceBlock) + "\n" + "{\n" + + interfaceBlockFieldString(interfaceBlock, blockStorage) + + "};\n\n"; +} + +TString OutputHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex) +{ + const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? decorate(str(arrayIndex)) : ""); + const TString &blockName = interfaceBlock.name() + arrayIndexString; + TString hlsl; + + hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n" + "{\n"; + + if (interfaceBlock.hasInstanceName()) + { + hlsl += " " + interfaceBlockStructNameString(interfaceBlock) + " " + interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n"; + } + else + { + const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage(); + hlsl += interfaceBlockFieldString(interfaceBlock, blockStorage); + } + + hlsl += "};\n\n"; + + return hlsl; +} + +TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex) +{ + if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray()) + { + // no padding needed, HLSL will align the field to a new register + *elementIndex = 0; + return ""; + } + + const GLenum glType = glVariableType(type); + const int numComponents = gl::UniformComponentCount(glType); + + if (numComponents >= 4) + { + // no padding needed, HLSL will align the field to a new register + *elementIndex = 0; + return ""; + } + + if (*elementIndex + numComponents > 4) + { + // no padding needed, HLSL will align the field to a new register + *elementIndex = numComponents; + return ""; + } + + TString padding; + + const int alignment = numComponents == 3 ? 4 : numComponents; + const int paddingOffset = (*elementIndex % alignment); + + if (paddingOffset != 0) + { + // padding is neccessary + for (int paddingIndex = paddingOffset; paddingIndex < alignment; paddingIndex++) + { + padding += " float pad_" + str(mPaddingCounter++) + ";\n"; + } + + *elementIndex += (alignment - paddingOffset); + } + + *elementIndex += numComponents; + *elementIndex %= 4; + + return padding; +} + +TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking) +{ + if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct) + { + return ""; + } + + int numComponents = 0; + + if (type.isMatrix()) + { + // This method can also be called from structureString, which does not use layout qualifiers. + // Thus, use the method parameter for determining the matrix packing. + // + // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we + // wish to always transpose GL matrices to play well with HLSL's matrix array indexing. + // + const bool isRowMajorMatrix = !useHLSLRowMajorPacking; + const GLenum glType = glVariableType(type); + numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); + } + else if (type.getStruct()) + { + const TString &structName = structureTypeName(*type.getStruct(), useHLSLRowMajorPacking, true); + numComponents = mStd140StructElementIndexes[structName]; + + if (numComponents == 0) + { + return ""; + } + } + else + { + const GLenum glType = glVariableType(type); + numComponents = gl::UniformComponentCount(glType); + } + + TString padding; + for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++) + { + padding += " float pad_" + str(mPaddingCounter++) + ";\n"; + } + return padding; +} + +// Use the same layout for packed and shared +void setBlockLayout(gl::InterfaceBlock *interfaceBlock, gl::BlockLayoutType newLayout) +{ + interfaceBlock->layout = newLayout; + interfaceBlock->blockInfo.clear(); + + switch (newLayout) + { + case gl::BLOCKLAYOUT_SHARED: + case gl::BLOCKLAYOUT_PACKED: + { + gl::HLSLBlockEncoder hlslEncoder(&interfaceBlock->blockInfo, gl::HLSLBlockEncoder::ENCODE_PACKED); + hlslEncoder.encodeInterfaceBlockFields(interfaceBlock->fields); + interfaceBlock->dataSize = hlslEncoder.getBlockSize(); + } + break; + + case gl::BLOCKLAYOUT_STANDARD: + { + gl::Std140BlockEncoder stdEncoder(&interfaceBlock->blockInfo); + stdEncoder.encodeInterfaceBlockFields(interfaceBlock->fields); + interfaceBlock->dataSize = stdEncoder.getBlockSize(); + } + break; + + default: + UNREACHABLE(); + break; + } +} + +gl::BlockLayoutType convertBlockLayoutType(TLayoutBlockStorage blockStorage) +{ + switch (blockStorage) + { + case EbsPacked: return gl::BLOCKLAYOUT_PACKED; + case EbsShared: return gl::BLOCKLAYOUT_SHARED; + case EbsStd140: return gl::BLOCKLAYOUT_STANDARD; + default: UNREACHABLE(); return gl::BLOCKLAYOUT_SHARED; + } +} + +TString OutputHLSL::structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName) +{ + TString init; + + TString preIndentString; + TString fullIndentString; + + for (int spaces = 0; spaces < (indent * 4); spaces++) + { + preIndentString += ' '; + } + + for (int spaces = 0; spaces < ((indent+1) * 4); spaces++) + { + fullIndentString += ' '; + } + + init += preIndentString + "{\n"; + + const TFieldList &fields = structure.fields(); + for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + { + const TField &field = *fields[fieldIndex]; + const TString &fieldName = rhsStructName + "." + decorate(field.name()); + const TType &fieldType = *field.type(); + + if (fieldType.getStruct()) + { + init += structInitializerString(indent + 1, *fieldType.getStruct(), fieldName); + } + else + { + init += fullIndentString + fieldName + ",\n"; + } + } + + init += preIndentString + "}" + (indent == 0 ? ";" : ",") + "\n"; + + return init; +} + +void OutputHLSL::header() +{ + TInfoSinkBase &out = mHeader; + + TString uniforms; + TString interfaceBlocks; + TString varyings; + TString attributes; + TString flaggedStructs; + + for (ReferencedSymbols::const_iterator uniformIt = mReferencedUniforms.begin(); uniformIt != mReferencedUniforms.end(); uniformIt++) + { + const TIntermSymbol &uniform = *uniformIt->second; + const TType &type = uniform.getType(); + const TString &name = uniform.getSymbol(); + + int registerIndex = declareUniformAndAssignRegister(type, name); + + if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture + { + uniforms += "uniform " + samplerString(type) + " sampler_" + decorateUniform(name, type) + arrayString(type) + + " : register(s" + str(registerIndex) + ");\n"; + + uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) + + " : register(t" + str(registerIndex) + ");\n"; + } + else + { + const TStructure *structure = type.getStruct(); + const TString &typeName = (structure ? structureTypeName(*structure, false, false) : typeString(type)); + + const TString ®isterString = TString("register(") + RegisterPrefix(type) + str(registerIndex) + ")"; + + uniforms += "uniform " + typeName + " " + decorateUniform(name, type) + arrayString(type) + " : " + registerString + ";\n"; + } + } + + for (ReferencedSymbols::const_iterator interfaceBlockIt = mReferencedInterfaceBlocks.begin(); interfaceBlockIt != mReferencedInterfaceBlocks.end(); interfaceBlockIt++) + { + const TType &nodeType = interfaceBlockIt->second->getType(); + const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock(); + const TFieldList &fieldList = interfaceBlock.fields(); + + unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize()); + gl::InterfaceBlock activeBlock(interfaceBlock.name().c_str(), arraySize, mInterfaceBlockRegister); + for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++) + { + const TField &field = *fieldList[typeIndex]; + const TString &fullUniformName = interfaceBlockFieldString(interfaceBlock, field); + declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields); + } + + mInterfaceBlockRegister += std::max(1u, arraySize); + + gl::BlockLayoutType blockLayoutType = convertBlockLayoutType(interfaceBlock.blockStorage()); + setBlockLayout(&activeBlock, blockLayoutType); + + if (interfaceBlock.matrixPacking() == EmpRowMajor) + { + activeBlock.isRowMajorLayout = true; + } + + mActiveInterfaceBlocks.push_back(activeBlock); + + if (interfaceBlock.hasInstanceName()) + { + interfaceBlocks += interfaceBlockStructString(interfaceBlock); + } + + if (arraySize > 0) + { + for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) + { + interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex + arrayIndex, arrayIndex); + } + } + else + { + interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex, GL_INVALID_INDEX); + } + } + + for (std::map<TIntermTyped*, TString>::const_iterator flaggedStructIt = mFlaggedStructMappedNames.begin(); flaggedStructIt != mFlaggedStructMappedNames.end(); flaggedStructIt++) + { + TIntermTyped *structNode = flaggedStructIt->first; + const TString &mappedName = flaggedStructIt->second; + const TStructure &structure = *structNode->getType().getStruct(); + const TString &originalName = mFlaggedStructOriginalNames[structNode]; + + flaggedStructs += "static " + decorate(structure.name()) + " " + mappedName + " =\n"; + flaggedStructs += structInitializerString(0, structure, originalName); + flaggedStructs += "\n"; + } + + for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++) + { + const TType &type = varying->second->getType(); + const TString &name = varying->second->getSymbol(); + + // Program linking depends on this exact format + varyings += "static " + interpolationString(type.getQualifier()) + " " + typeString(type) + " " + + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n"; + + declareVaryingToList(type, type.getQualifier(), name, mActiveVaryings); + } + + for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++) + { + const TType &type = attribute->second->getType(); + const TString &name = attribute->second->getSymbol(); + + attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n"; + + gl::Attribute attributeVar(glVariableType(type), glVariablePrecision(type), name.c_str(), + (unsigned int)type.getArraySize(), type.getLayoutQualifier().location); + mActiveAttributes.push_back(attributeVar); + } + + for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++) + { + out << *structDeclaration; + } + + for (Constructors::iterator constructor = mConstructors.begin(); constructor != mConstructors.end(); constructor++) + { + out << *constructor; + } + + if (mUsesDiscardRewriting) + { + out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n"; + } + + if (mUsesNestedBreak) + { + out << "#define ANGLE_USES_NESTED_BREAK" << "\n"; + } + + if (mContext.shaderType == SH_FRAGMENT_SHADER) + { + TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers"); + const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire)); + + out << "// Varyings\n"; + out << varyings; + out << "\n"; + + if (mContext.getShaderVersion() >= 300) + { + for (ReferencedSymbols::const_iterator outputVariableIt = mReferencedOutputVariables.begin(); outputVariableIt != mReferencedOutputVariables.end(); outputVariableIt++) + { + const TString &variableName = outputVariableIt->first; + const TType &variableType = outputVariableIt->second->getType(); + const TLayoutQualifier &layoutQualifier = variableType.getLayoutQualifier(); + + out << "static " + typeString(variableType) + " out_" + variableName + arrayString(variableType) + + " = " + initializer(variableType) + ";\n"; + + gl::Attribute outputVar(glVariableType(variableType), glVariablePrecision(variableType), variableName.c_str(), + (unsigned int)variableType.getArraySize(), layoutQualifier.location); + mActiveOutputVariables.push_back(outputVar); + } + } + else + { + const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1; + + out << "static float4 gl_Color[" << numColorValues << "] =\n" + "{\n"; + for (unsigned int i = 0; i < numColorValues; i++) + { + out << " float4(0, 0, 0, 0)"; + if (i + 1 != numColorValues) + { + out << ","; + } + out << "\n"; + } + + out << "};\n"; + } + + if (mUsesFragDepth) + { + out << "static float gl_Depth = 0.0;\n"; + } + + if (mUsesFragCoord) + { + out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n"; + } + + if (mUsesPointCoord) + { + out << "static float2 gl_PointCoord = float2(0.5, 0.5);\n"; + } + + if (mUsesFrontFacing) + { + out << "static bool gl_FrontFacing = false;\n"; + } + + out << "\n"; + + if (mUsesDepthRange) + { + out << "struct gl_DepthRangeParameters\n" + "{\n" + " float near;\n" + " float far;\n" + " float diff;\n" + "};\n" + "\n"; + } + + if (mOutputType == SH_HLSL11_OUTPUT) + { + out << "cbuffer DriverConstants : register(b1)\n" + "{\n"; + + if (mUsesDepthRange) + { + out << " float3 dx_DepthRange : packoffset(c0);\n"; + } + + if (mUsesFragCoord) + { + out << " float4 dx_ViewCoords : packoffset(c1);\n"; + } + + if (mUsesFragCoord || mUsesFrontFacing) + { + out << " float3 dx_DepthFront : packoffset(c2);\n"; + } + + out << "};\n"; + } + else + { + if (mUsesDepthRange) + { + out << "uniform float3 dx_DepthRange : register(c0);"; + } + + if (mUsesFragCoord) + { + out << "uniform float4 dx_ViewCoords : register(c1);\n"; + } + + if (mUsesFragCoord || mUsesFrontFacing) + { + out << "uniform float3 dx_DepthFront : register(c2);\n"; + } + } + + out << "\n"; + + if (mUsesDepthRange) + { + out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" + "\n"; + } + + out << uniforms; + out << "\n"; + + if (!interfaceBlocks.empty()) + { + out << interfaceBlocks; + out << "\n"; + + if (!flaggedStructs.empty()) + { + out << "// Std140 Structures accessed by value\n"; + out << "\n"; + out << flaggedStructs; + out << "\n"; + } + } + + if (usingMRTExtension && mNumRenderTargets > 1) + { + out << "#define GL_USES_MRT\n"; + } + + if (mUsesFragColor) + { + out << "#define GL_USES_FRAG_COLOR\n"; + } + + if (mUsesFragData) + { + out << "#define GL_USES_FRAG_DATA\n"; + } + } + else // Vertex shader + { + out << "// Attributes\n"; + out << attributes; + out << "\n" + "static float4 gl_Position = float4(0, 0, 0, 0);\n"; + + if (mUsesPointSize) + { + out << "static float gl_PointSize = float(1);\n"; + } + + out << "\n" + "// Varyings\n"; + out << varyings; + out << "\n"; + + if (mUsesDepthRange) + { + out << "struct gl_DepthRangeParameters\n" + "{\n" + " float near;\n" + " float far;\n" + " float diff;\n" + "};\n" + "\n"; + } + + if (mOutputType == SH_HLSL11_OUTPUT) + { + if (mUsesDepthRange) + { + out << "cbuffer DriverConstants : register(b1)\n" + "{\n" + " float3 dx_DepthRange : packoffset(c0);\n" + "};\n" + "\n"; + } + } + else + { + if (mUsesDepthRange) + { + out << "uniform float3 dx_DepthRange : register(c0);\n"; + } + + out << "uniform float4 dx_ViewAdjust : register(c1);\n" + "\n"; + } + + if (mUsesDepthRange) + { + out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" + "\n"; + } + + out << uniforms; + out << "\n"; + + if (!interfaceBlocks.empty()) + { + out << interfaceBlocks; + out << "\n"; + + if (!flaggedStructs.empty()) + { + out << "// Std140 Structures accessed by value\n"; + out << "\n"; + out << flaggedStructs; + out << "\n"; + } + } + } + + for (TextureFunctionSet::const_iterator textureFunction = mUsesTexture.begin(); textureFunction != mUsesTexture.end(); textureFunction++) + { + // Return type + if (textureFunction->method == TextureFunction::SIZE) + { + switch(textureFunction->sampler) + { + case EbtSampler2D: out << "int2 "; break; + case EbtSampler3D: out << "int3 "; break; + case EbtSamplerCube: out << "int2 "; break; + case EbtSampler2DArray: out << "int3 "; break; + case EbtISampler2D: out << "int2 "; break; + case EbtISampler3D: out << "int3 "; break; + case EbtISamplerCube: out << "int2 "; break; + case EbtISampler2DArray: out << "int3 "; break; + case EbtUSampler2D: out << "int2 "; break; + case EbtUSampler3D: out << "int3 "; break; + case EbtUSamplerCube: out << "int2 "; break; + case EbtUSampler2DArray: out << "int3 "; break; + case EbtSampler2DShadow: out << "int2 "; break; + case EbtSamplerCubeShadow: out << "int2 "; break; + case EbtSampler2DArrayShadow: out << "int3 "; break; + default: UNREACHABLE(); + } + } + else // Sampling function + { + switch(textureFunction->sampler) + { + case EbtSampler2D: out << "float4 "; break; + case EbtSampler3D: out << "float4 "; break; + case EbtSamplerCube: out << "float4 "; break; + case EbtSampler2DArray: out << "float4 "; break; + case EbtISampler2D: out << "int4 "; break; + case EbtISampler3D: out << "int4 "; break; + case EbtISamplerCube: out << "int4 "; break; + case EbtISampler2DArray: out << "int4 "; break; + case EbtUSampler2D: out << "uint4 "; break; + case EbtUSampler3D: out << "uint4 "; break; + case EbtUSamplerCube: out << "uint4 "; break; + case EbtUSampler2DArray: out << "uint4 "; break; + case EbtSampler2DShadow: out << "float "; break; + case EbtSamplerCubeShadow: out << "float "; break; + case EbtSampler2DArrayShadow: out << "float "; break; + default: UNREACHABLE(); + } + } + + // Function name + out << textureFunction->name(); + + // Argument list + int hlslCoords = 4; + + if (mOutputType == SH_HLSL9_OUTPUT) + { + switch(textureFunction->sampler) + { + case EbtSampler2D: out << "sampler2D s"; hlslCoords = 2; break; + case EbtSamplerCube: out << "samplerCUBE s"; hlslCoords = 3; break; + default: UNREACHABLE(); + } + + switch(textureFunction->method) + { + case TextureFunction::IMPLICIT: break; + case TextureFunction::BIAS: hlslCoords = 4; break; + case TextureFunction::LOD: hlslCoords = 4; break; + case TextureFunction::LOD0: hlslCoords = 4; break; + case TextureFunction::LOD0BIAS: hlslCoords = 4; break; + default: UNREACHABLE(); + } + } + else if (mOutputType == SH_HLSL11_OUTPUT) + { + switch(textureFunction->sampler) + { + case EbtSampler2D: out << "Texture2D x, SamplerState s"; hlslCoords = 2; break; + case EbtSampler3D: out << "Texture3D x, SamplerState s"; hlslCoords = 3; break; + case EbtSamplerCube: out << "TextureCube x, SamplerState s"; hlslCoords = 3; break; + case EbtSampler2DArray: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break; + case EbtISampler2D: out << "Texture2D<int4> x, SamplerState s"; hlslCoords = 2; break; + case EbtISampler3D: out << "Texture3D<int4> x, SamplerState s"; hlslCoords = 3; break; + case EbtISamplerCube: out << "Texture2DArray<int4> x, SamplerState s"; hlslCoords = 3; break; + case EbtISampler2DArray: out << "Texture2DArray<int4> x, SamplerState s"; hlslCoords = 3; break; + case EbtUSampler2D: out << "Texture2D<uint4> x, SamplerState s"; hlslCoords = 2; break; + case EbtUSampler3D: out << "Texture3D<uint4> x, SamplerState s"; hlslCoords = 3; break; + case EbtUSamplerCube: out << "Texture2DArray<uint4> x, SamplerState s"; hlslCoords = 3; break; + case EbtUSampler2DArray: out << "Texture2DArray<uint4> x, SamplerState s"; hlslCoords = 3; break; + case EbtSampler2DShadow: out << "Texture2D x, SamplerComparisonState s"; hlslCoords = 2; break; + case EbtSamplerCubeShadow: out << "TextureCube x, SamplerComparisonState s"; hlslCoords = 3; break; + case EbtSampler2DArrayShadow: out << "Texture2DArray x, SamplerComparisonState s"; hlslCoords = 3; break; + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + + if (textureFunction->method == TextureFunction::FETCH) // Integer coordinates + { + switch(textureFunction->coords) + { + case 2: out << ", int2 t"; break; + case 3: out << ", int3 t"; break; + default: UNREACHABLE(); + } + } + else // Floating-point coordinates (except textureSize) + { + switch(textureFunction->coords) + { + case 1: out << ", int lod"; break; // textureSize() + case 2: out << ", float2 t"; break; + case 3: out << ", float3 t"; break; + case 4: out << ", float4 t"; break; + default: UNREACHABLE(); + } + } + + if (textureFunction->method == TextureFunction::GRAD) + { + switch(textureFunction->sampler) + { + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + out << ", float2 ddx, float2 ddy"; + break; + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCubeShadow: + out << ", float3 ddx, float3 ddy"; + break; + default: UNREACHABLE(); + } + } + + switch(textureFunction->method) + { + case TextureFunction::IMPLICIT: break; + case TextureFunction::BIAS: break; // Comes after the offset parameter + case TextureFunction::LOD: out << ", float lod"; break; + case TextureFunction::LOD0: break; + case TextureFunction::LOD0BIAS: break; // Comes after the offset parameter + case TextureFunction::SIZE: break; + case TextureFunction::FETCH: out << ", int mip"; break; + case TextureFunction::GRAD: break; + default: UNREACHABLE(); + } + + if (textureFunction->offset) + { + switch(textureFunction->sampler) + { + case EbtSampler2D: out << ", int2 offset"; break; + case EbtSampler3D: out << ", int3 offset"; break; + case EbtSampler2DArray: out << ", int2 offset"; break; + case EbtISampler2D: out << ", int2 offset"; break; + case EbtISampler3D: out << ", int3 offset"; break; + case EbtISampler2DArray: out << ", int2 offset"; break; + case EbtUSampler2D: out << ", int2 offset"; break; + case EbtUSampler3D: out << ", int3 offset"; break; + case EbtUSampler2DArray: out << ", int2 offset"; break; + case EbtSampler2DShadow: out << ", int2 offset"; break; + case EbtSampler2DArrayShadow: out << ", int2 offset"; break; + default: UNREACHABLE(); + } + } + + if (textureFunction->method == TextureFunction::BIAS || + textureFunction->method == TextureFunction::LOD0BIAS) + { + out << ", float bias"; + } + + out << ")\n" + "{\n"; + + if (textureFunction->method == TextureFunction::SIZE) + { + if (IsSampler2D(textureFunction->sampler) || IsSamplerCube(textureFunction->sampler)) + { + if (IsSamplerArray(textureFunction->sampler)) + { + out << " uint width; uint height; uint layers; uint numberOfLevels;\n" + " x.GetDimensions(lod, width, height, layers, numberOfLevels);\n"; + } + else + { + out << " uint width; uint height; uint numberOfLevels;\n" + " x.GetDimensions(lod, width, height, numberOfLevels);\n"; + } + } + else if (IsSampler3D(textureFunction->sampler)) + { + out << " uint width; uint height; uint depth; uint numberOfLevels;\n" + " x.GetDimensions(lod, width, height, depth, numberOfLevels);\n"; + } + else UNREACHABLE(); + + switch(textureFunction->sampler) + { + case EbtSampler2D: out << " return int2(width, height);"; break; + case EbtSampler3D: out << " return int3(width, height, depth);"; break; + case EbtSamplerCube: out << " return int2(width, height);"; break; + case EbtSampler2DArray: out << " return int3(width, height, layers);"; break; + case EbtISampler2D: out << " return int2(width, height);"; break; + case EbtISampler3D: out << " return int3(width, height, depth);"; break; + case EbtISamplerCube: out << " return int2(width, height);"; break; + case EbtISampler2DArray: out << " return int3(width, height, layers);"; break; + case EbtUSampler2D: out << " return int2(width, height);"; break; + case EbtUSampler3D: out << " return int3(width, height, depth);"; break; + case EbtUSamplerCube: out << " return int2(width, height);"; break; + case EbtUSampler2DArray: out << " return int3(width, height, layers);"; break; + case EbtSampler2DShadow: out << " return int2(width, height);"; break; + case EbtSamplerCubeShadow: out << " return int2(width, height);"; break; + case EbtSampler2DArrayShadow: out << " return int3(width, height, layers);"; break; + default: UNREACHABLE(); + } + } + else + { + if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler)) + { + out << " float width; float height; float layers; float levels;\n"; + + out << " uint mip = 0;\n"; + + out << " x.GetDimensions(mip, width, height, layers, levels);\n"; + + out << " bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n"; + out << " bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n"; + out << " bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n"; + out << " bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || (zMajor && t.z < 0.0f);\n"; + + // FACE_POSITIVE_X = 000b + // FACE_NEGATIVE_X = 001b + // FACE_POSITIVE_Y = 010b + // FACE_NEGATIVE_Y = 011b + // FACE_POSITIVE_Z = 100b + // FACE_NEGATIVE_Z = 101b + out << " int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n"; + + out << " float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n"; + out << " float v = yMajor ? t.z : (negative ? t.y : -t.y);\n"; + out << " float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n"; + + out << " t.x = (u * 0.5f / m) + 0.5f;\n"; + out << " t.y = (v * 0.5f / m) + 0.5f;\n"; + } + else if (IsIntegerSampler(textureFunction->sampler) && + textureFunction->method != TextureFunction::FETCH) + { + if (IsSampler2D(textureFunction->sampler)) + { + if (IsSamplerArray(textureFunction->sampler)) + { + out << " float width; float height; float layers; float levels;\n"; + + if (textureFunction->method == TextureFunction::LOD0) + { + out << " uint mip = 0;\n"; + } + else if (textureFunction->method == TextureFunction::LOD0BIAS) + { + out << " uint mip = bias;\n"; + } + else + { + if (textureFunction->method == TextureFunction::IMPLICIT || + textureFunction->method == TextureFunction::BIAS) + { + out << " x.GetDimensions(0, width, height, layers, levels);\n" + " float2 tSized = float2(t.x * width, t.y * height);\n" + " float dx = length(ddx(tSized));\n" + " float dy = length(ddy(tSized));\n" + " float lod = log2(max(dx, dy));\n"; + + if (textureFunction->method == TextureFunction::BIAS) + { + out << " lod += bias;\n"; + } + } + else if (textureFunction->method == TextureFunction::GRAD) + { + out << " x.GetDimensions(0, width, height, layers, levels);\n" + " float lod = log2(max(length(ddx), length(ddy)));\n"; + } + + out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; + } + + out << " x.GetDimensions(mip, width, height, layers, levels);\n"; + } + else + { + out << " float width; float height; float levels;\n"; + + if (textureFunction->method == TextureFunction::LOD0) + { + out << " uint mip = 0;\n"; + } + else if (textureFunction->method == TextureFunction::LOD0BIAS) + { + out << " uint mip = bias;\n"; + } + else + { + if (textureFunction->method == TextureFunction::IMPLICIT || + textureFunction->method == TextureFunction::BIAS) + { + out << " x.GetDimensions(0, width, height, levels);\n" + " float2 tSized = float2(t.x * width, t.y * height);\n" + " float dx = length(ddx(tSized));\n" + " float dy = length(ddy(tSized));\n" + " float lod = log2(max(dx, dy));\n"; + + if (textureFunction->method == TextureFunction::BIAS) + { + out << " lod += bias;\n"; + } + } + else if (textureFunction->method == TextureFunction::LOD) + { + out << " x.GetDimensions(0, width, height, levels);\n"; + } + else if (textureFunction->method == TextureFunction::GRAD) + { + out << " x.GetDimensions(0, width, height, levels);\n" + " float lod = log2(max(length(ddx), length(ddy)));\n"; + } + + out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; + } + + out << " x.GetDimensions(mip, width, height, levels);\n"; + } + } + else if (IsSampler3D(textureFunction->sampler)) + { + out << " float width; float height; float depth; float levels;\n"; + + if (textureFunction->method == TextureFunction::LOD0) + { + out << " uint mip = 0;\n"; + } + else if (textureFunction->method == TextureFunction::LOD0BIAS) + { + out << " uint mip = bias;\n"; + } + else + { + if (textureFunction->method == TextureFunction::IMPLICIT || + textureFunction->method == TextureFunction::BIAS) + { + out << " x.GetDimensions(0, width, height, depth, levels);\n" + " float3 tSized = float3(t.x * width, t.y * height, t.z * depth);\n" + " float dx = length(ddx(tSized));\n" + " float dy = length(ddy(tSized));\n" + " float lod = log2(max(dx, dy));\n"; + + if (textureFunction->method == TextureFunction::BIAS) + { + out << " lod += bias;\n"; + } + } + else if (textureFunction->method == TextureFunction::GRAD) + { + out << " x.GetDimensions(0, width, height, depth, levels);\n" + " float lod = log2(max(length(ddx), length(ddy)));\n"; + } + + out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; + } + + out << " x.GetDimensions(mip, width, height, depth, levels);\n"; + } + else UNREACHABLE(); + } + + out << " return "; + + // HLSL intrinsic + if (mOutputType == SH_HLSL9_OUTPUT) + { + switch(textureFunction->sampler) + { + case EbtSampler2D: out << "tex2D"; break; + case EbtSamplerCube: out << "texCUBE"; break; + default: UNREACHABLE(); + } + + switch(textureFunction->method) + { + case TextureFunction::IMPLICIT: out << "(s, "; break; + case TextureFunction::BIAS: out << "bias(s, "; break; + case TextureFunction::LOD: out << "lod(s, "; break; + case TextureFunction::LOD0: out << "lod(s, "; break; + case TextureFunction::LOD0BIAS: out << "lod(s, "; break; + default: UNREACHABLE(); + } + } + else if (mOutputType == SH_HLSL11_OUTPUT) + { + if (textureFunction->method == TextureFunction::GRAD) + { + if (IsIntegerSampler(textureFunction->sampler)) + { + out << "x.Load("; + } + else if (IsShadowSampler(textureFunction->sampler)) + { + out << "x.SampleCmpLevelZero(s, "; + } + else + { + out << "x.SampleGrad(s, "; + } + } + else if (IsIntegerSampler(textureFunction->sampler) || + textureFunction->method == TextureFunction::FETCH) + { + out << "x.Load("; + } + else if (IsShadowSampler(textureFunction->sampler)) + { + out << "x.SampleCmp(s, "; + } + else + { + switch(textureFunction->method) + { + case TextureFunction::IMPLICIT: out << "x.Sample(s, "; break; + case TextureFunction::BIAS: out << "x.SampleBias(s, "; break; + case TextureFunction::LOD: out << "x.SampleLevel(s, "; break; + case TextureFunction::LOD0: out << "x.SampleLevel(s, "; break; + case TextureFunction::LOD0BIAS: out << "x.SampleLevel(s, "; break; + default: UNREACHABLE(); + } + } + } + else UNREACHABLE(); + + // Integer sampling requires integer addresses + TString addressx = ""; + TString addressy = ""; + TString addressz = ""; + TString close = ""; + + if (IsIntegerSampler(textureFunction->sampler) || + textureFunction->method == TextureFunction::FETCH) + { + switch(hlslCoords) + { + case 2: out << "int3("; break; + case 3: out << "int4("; break; + default: UNREACHABLE(); + } + + // Convert from normalized floating-point to integer + if (textureFunction->method != TextureFunction::FETCH) + { + addressx = "int(floor(width * frac(("; + addressy = "int(floor(height * frac(("; + + if (IsSamplerArray(textureFunction->sampler)) + { + addressz = "int(max(0, min(layers - 1, floor(0.5 + "; + } + else if (IsSamplerCube(textureFunction->sampler)) + { + addressz = "(((("; + } + else + { + addressz = "int(floor(depth * frac(("; + } + + close = "))))"; + } + } + else + { + switch(hlslCoords) + { + case 2: out << "float2("; break; + case 3: out << "float3("; break; + case 4: out << "float4("; break; + default: UNREACHABLE(); + } + } + + TString proj = ""; // Only used for projected textures + + if (textureFunction->proj) + { + switch(textureFunction->coords) + { + case 3: proj = " / t.z"; break; + case 4: proj = " / t.w"; break; + default: UNREACHABLE(); + } + } + + out << addressx + ("t.x" + proj) + close + ", " + addressy + ("t.y" + proj) + close; + + if (mOutputType == SH_HLSL9_OUTPUT) + { + if (hlslCoords >= 3) + { + if (textureFunction->coords < 3) + { + out << ", 0"; + } + else + { + out << ", t.z" + proj; + } + } + + if (hlslCoords == 4) + { + switch(textureFunction->method) + { + case TextureFunction::BIAS: out << ", bias"; break; + case TextureFunction::LOD: out << ", lod"; break; + case TextureFunction::LOD0: out << ", 0"; break; + case TextureFunction::LOD0BIAS: out << ", bias"; break; + default: UNREACHABLE(); + } + } + + out << "));\n"; + } + else if (mOutputType == SH_HLSL11_OUTPUT) + { + if (hlslCoords >= 3) + { + if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler)) + { + out << ", face"; + } + else + { + out << ", " + addressz + ("t.z" + proj) + close; + } + } + + if (textureFunction->method == TextureFunction::GRAD) + { + if (IsIntegerSampler(textureFunction->sampler)) + { + out << ", mip)"; + } + else if (IsShadowSampler(textureFunction->sampler)) + { + // Compare value + switch(textureFunction->coords) + { + case 3: out << "), t.z"; break; + case 4: out << "), t.w"; break; + default: UNREACHABLE(); + } + } + else + { + out << "), ddx, ddy"; + } + } + else if (IsIntegerSampler(textureFunction->sampler) || + textureFunction->method == TextureFunction::FETCH) + { + out << ", mip)"; + } + else if (IsShadowSampler(textureFunction->sampler)) + { + // Compare value + switch(textureFunction->coords) + { + case 3: out << "), t.z"; break; + case 4: out << "), t.w"; break; + default: UNREACHABLE(); + } + } + else + { + switch(textureFunction->method) + { + case TextureFunction::IMPLICIT: out << ")"; break; + case TextureFunction::BIAS: out << "), bias"; break; + case TextureFunction::LOD: out << "), lod"; break; + case TextureFunction::LOD0: out << "), 0"; break; + case TextureFunction::LOD0BIAS: out << "), bias"; break; + default: UNREACHABLE(); + } + } + + if (textureFunction->offset) + { + out << ", offset"; + } + + out << ");"; + } + else UNREACHABLE(); + } + + out << "\n" + "}\n" + "\n"; + } + + if (mUsesFragCoord) + { + out << "#define GL_USES_FRAG_COORD\n"; + } + + if (mUsesPointCoord) + { + out << "#define GL_USES_POINT_COORD\n"; + } + + if (mUsesFrontFacing) + { + out << "#define GL_USES_FRONT_FACING\n"; + } + + if (mUsesPointSize) + { + out << "#define GL_USES_POINT_SIZE\n"; + } + + if (mUsesFragDepth) + { + out << "#define GL_USES_FRAG_DEPTH\n"; + } + + if (mUsesDepthRange) + { + out << "#define GL_USES_DEPTH_RANGE\n"; + } + + if (mUsesXor) + { + out << "bool xor(bool p, bool q)\n" + "{\n" + " return (p || q) && !(p && q);\n" + "}\n" + "\n"; + } + + if (mUsesMod1) + { + out << "float mod(float x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod2v) + { + out << "float2 mod(float2 x, float2 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod2f) + { + out << "float2 mod(float2 x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod3v) + { + out << "float3 mod(float3 x, float3 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod3f) + { + out << "float3 mod(float3 x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod4v) + { + out << "float4 mod(float4 x, float4 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod4f) + { + out << "float4 mod(float4 x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesFaceforward1) + { + out << "float faceforward(float N, float I, float Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n" + "\n"; + } + + if (mUsesFaceforward2) + { + out << "float2 faceforward(float2 N, float2 I, float2 Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n" + "\n"; + } + + if (mUsesFaceforward3) + { + out << "float3 faceforward(float3 N, float3 I, float3 Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n" + "\n"; + } + + if (mUsesFaceforward4) + { + out << "float4 faceforward(float4 N, float4 I, float4 Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n" + "\n"; + } + + if (mUsesAtan2_1) + { + out << "float atanyx(float y, float x)\n" + "{\n" + " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN + " return atan2(y, x);\n" + "}\n"; + } + + if (mUsesAtan2_2) + { + out << "float2 atanyx(float2 y, float2 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n" + "}\n"; + } + + if (mUsesAtan2_3) + { + out << "float3 atanyx(float3 y, float3 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" + " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n" + "}\n"; + } + + if (mUsesAtan2_4) + { + out << "float4 atanyx(float4 y, float4 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" + " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n" + " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n" + "}\n"; + } +} + +void OutputHLSL::visitSymbol(TIntermSymbol *node) +{ + TInfoSinkBase &out = mBody; + + // Handle accessing std140 structs by value + if (mFlaggedStructMappedNames.count(node) > 0) + { + out << mFlaggedStructMappedNames[node]; + return; + } + + TString name = node->getSymbol(); + + if (name == "gl_DepthRange") + { + mUsesDepthRange = true; + out << name; + } + else + { + TQualifier qualifier = node->getQualifier(); + + if (qualifier == EvqUniform) + { + const TType& nodeType = node->getType(); + const TInterfaceBlock* interfaceBlock = nodeType.getInterfaceBlock(); + + if (interfaceBlock) + { + mReferencedInterfaceBlocks[interfaceBlock->name()] = node; + } + else + { + mReferencedUniforms[name] = node; + } + + out << decorateUniform(name, nodeType); + } + else if (qualifier == EvqAttribute || qualifier == EvqVertexIn) + { + mReferencedAttributes[name] = node; + out << decorate(name); + } + else if (isVarying(qualifier)) + { + mReferencedVaryings[name] = node; + out << decorate(name); + } + else if (qualifier == EvqFragmentOut) + { + mReferencedOutputVariables[name] = node; + out << "out_" << name; + } + else if (qualifier == EvqFragColor) + { + out << "gl_Color[0]"; + mUsesFragColor = true; + } + else if (qualifier == EvqFragData) + { + out << "gl_Color"; + mUsesFragData = true; + } + else if (qualifier == EvqFragCoord) + { + mUsesFragCoord = true; + out << name; + } + else if (qualifier == EvqPointCoord) + { + mUsesPointCoord = true; + out << name; + } + else if (qualifier == EvqFrontFacing) + { + mUsesFrontFacing = true; + out << name; + } + else if (qualifier == EvqPointSize) + { + mUsesPointSize = true; + out << name; + } + else if (name == "gl_FragDepthEXT") + { + mUsesFragDepth = true; + out << "gl_Depth"; + } + else if (qualifier == EvqInternal) + { + out << name; + } + else + { + out << decorate(name); + } + } +} + +void OutputHLSL::visitRaw(TIntermRaw *node) +{ + mBody << node->getRawText(); +} + +bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) +{ + TInfoSinkBase &out = mBody; + + // Handle accessing std140 structs by value + if (mFlaggedStructMappedNames.count(node) > 0) + { + out << mFlaggedStructMappedNames[node]; + return false; + } + + switch (node->getOp()) + { + case EOpAssign: outputTriplet(visit, "(", " = ", ")"); break; + case EOpInitialize: + if (visit == PreVisit) + { + // GLSL allows to write things like "float x = x;" where a new variable x is defined + // and the value of an existing variable x is assigned. HLSL uses C semantics (the + // new variable is created before the assignment is evaluated), so we need to convert + // this to "float t = x, x = t;". + + TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode(); + TIntermTyped *expression = node->getRight(); + + sh::SearchSymbol searchSymbol(symbolNode->getSymbol()); + expression->traverse(&searchSymbol); + bool sameSymbol = searchSymbol.foundMatch(); + + if (sameSymbol) + { + // Type already printed + out << "t" + str(mUniqueIndex) + " = "; + expression->traverse(this); + out << ", "; + symbolNode->traverse(this); + out << " = t" + str(mUniqueIndex); + + mUniqueIndex++; + return false; + } + } + else if (visit == InVisit) + { + out << " = "; + } + break; + case EOpAddAssign: outputTriplet(visit, "(", " += ", ")"); break; + case EOpSubAssign: outputTriplet(visit, "(", " -= ", ")"); break; + case EOpMulAssign: outputTriplet(visit, "(", " *= ", ")"); break; + case EOpVectorTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break; + case EOpMatrixTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break; + case EOpVectorTimesMatrixAssign: + if (visit == PreVisit) + { + out << "("; + } + else if (visit == InVisit) + { + out << " = mul("; + node->getLeft()->traverse(this); + out << ", transpose("; + } + else + { + out << ")))"; + } + break; + case EOpMatrixTimesMatrixAssign: + if (visit == PreVisit) + { + out << "("; + } + else if (visit == InVisit) + { + out << " = mul("; + node->getLeft()->traverse(this); + out << ", "; + } + else + { + out << "))"; + } + break; + case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break; + case EOpIndexDirect: + { + const TType& leftType = node->getLeft()->getType(); + if (leftType.isInterfaceBlock()) + { + if (visit == PreVisit) + { + TInterfaceBlock* interfaceBlock = leftType.getInterfaceBlock(); + const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0); + + mReferencedInterfaceBlocks[interfaceBlock->instanceName()] = node->getLeft()->getAsSymbolNode(); + out << interfaceBlockInstanceString(*interfaceBlock, arrayIndex); + + return false; + } + } + else + { + outputTriplet(visit, "", "[", "]"); + } + } + break; + case EOpIndexIndirect: + // We do not currently support indirect references to interface blocks + ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock); + outputTriplet(visit, "", "[", "]"); + break; + case EOpIndexDirectStruct: + if (visit == InVisit) + { + const TStructure* structure = node->getLeft()->getType().getStruct(); + const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); + const TField* field = structure->fields()[index->getIConst(0)]; + out << "." + decorateField(field->name(), *structure); + + return false; + } + break; + case EOpIndexDirectInterfaceBlock: + if (visit == InVisit) + { + const TInterfaceBlock* interfaceBlock = node->getLeft()->getType().getInterfaceBlock(); + const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); + const TField* field = interfaceBlock->fields()[index->getIConst(0)]; + out << "." + decorate(field->name()); + + return false; + } + break; + case EOpVectorSwizzle: + if (visit == InVisit) + { + out << "."; + + TIntermAggregate *swizzle = node->getRight()->getAsAggregate(); + + if (swizzle) + { + TIntermSequence &sequence = swizzle->getSequence(); + + for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) + { + TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); + + if (element) + { + int i = element->getIConst(0); + + switch (i) + { + case 0: out << "x"; break; + case 1: out << "y"; break; + case 2: out << "z"; break; + case 3: out << "w"; break; + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + } + } + else UNREACHABLE(); + + return false; // Fully processed + } + break; + case EOpAdd: outputTriplet(visit, "(", " + ", ")"); break; + case EOpSub: outputTriplet(visit, "(", " - ", ")"); break; + case EOpMul: outputTriplet(visit, "(", " * ", ")"); break; + case EOpDiv: outputTriplet(visit, "(", " / ", ")"); break; + case EOpEqual: + case EOpNotEqual: + if (node->getLeft()->isScalar()) + { + if (node->getOp() == EOpEqual) + { + outputTriplet(visit, "(", " == ", ")"); + } + else + { + outputTriplet(visit, "(", " != ", ")"); + } + } + else if (node->getLeft()->getBasicType() == EbtStruct) + { + if (node->getOp() == EOpEqual) + { + out << "("; + } + else + { + out << "!("; + } + + const TStructure &structure = *node->getLeft()->getType().getStruct(); + const TFieldList &fields = structure.fields(); + + for (size_t i = 0; i < fields.size(); i++) + { + const TField *field = fields[i]; + + node->getLeft()->traverse(this); + out << "." + decorateField(field->name(), structure) + " == "; + node->getRight()->traverse(this); + out << "." + decorateField(field->name(), structure); + + if (i < fields.size() - 1) + { + out << " && "; + } + } + + out << ")"; + + return false; + } + else + { + ASSERT(node->getLeft()->isMatrix() || node->getLeft()->isVector()); + + if (node->getOp() == EOpEqual) + { + outputTriplet(visit, "all(", " == ", ")"); + } + else + { + outputTriplet(visit, "!all(", " == ", ")"); + } + } + break; + case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; + case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; + case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break; + case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break; + case EOpVectorTimesScalar: outputTriplet(visit, "(", " * ", ")"); break; + case EOpMatrixTimesScalar: outputTriplet(visit, "(", " * ", ")"); break; + case EOpVectorTimesMatrix: outputTriplet(visit, "mul(", ", transpose(", "))"); break; + case EOpMatrixTimesVector: outputTriplet(visit, "mul(transpose(", "), ", ")"); break; + case EOpMatrixTimesMatrix: outputTriplet(visit, "transpose(mul(transpose(", "), transpose(", ")))"); break; + case EOpLogicalOr: + if (node->getRight()->hasSideEffects()) + { + out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); + return false; + } + else + { + outputTriplet(visit, "(", " || ", ")"); + return true; + } + case EOpLogicalXor: + mUsesXor = true; + outputTriplet(visit, "xor(", ", ", ")"); + break; + case EOpLogicalAnd: + if (node->getRight()->hasSideEffects()) + { + out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); + return false; + } + else + { + outputTriplet(visit, "(", " && ", ")"); + return true; + } + default: UNREACHABLE(); + } + + return true; +} + +bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) +{ + switch (node->getOp()) + { + case EOpNegative: outputTriplet(visit, "(-", "", ")"); break; + case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break; + case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break; + case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break; + case EOpPostDecrement: outputTriplet(visit, "(", "", "--)"); break; + case EOpPreIncrement: outputTriplet(visit, "(++", "", ")"); break; + case EOpPreDecrement: outputTriplet(visit, "(--", "", ")"); break; + case EOpConvIntToBool: + case EOpConvUIntToBool: + case EOpConvFloatToBool: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: outputTriplet(visit, "bool(", "", ")"); break; + case 2: outputTriplet(visit, "bool2(", "", ")"); break; + case 3: outputTriplet(visit, "bool3(", "", ")"); break; + case 4: outputTriplet(visit, "bool4(", "", ")"); break; + default: UNREACHABLE(); + } + break; + case EOpConvBoolToFloat: + case EOpConvIntToFloat: + case EOpConvUIntToFloat: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: outputTriplet(visit, "float(", "", ")"); break; + case 2: outputTriplet(visit, "float2(", "", ")"); break; + case 3: outputTriplet(visit, "float3(", "", ")"); break; + case 4: outputTriplet(visit, "float4(", "", ")"); break; + default: UNREACHABLE(); + } + break; + case EOpConvFloatToInt: + case EOpConvBoolToInt: + case EOpConvUIntToInt: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: outputTriplet(visit, "int(", "", ")"); break; + case 2: outputTriplet(visit, "int2(", "", ")"); break; + case 3: outputTriplet(visit, "int3(", "", ")"); break; + case 4: outputTriplet(visit, "int4(", "", ")"); break; + default: UNREACHABLE(); + } + break; + case EOpConvFloatToUInt: + case EOpConvBoolToUInt: + case EOpConvIntToUInt: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: outputTriplet(visit, "uint(", "", ")"); break; + case 2: outputTriplet(visit, "uint2(", "", ")"); break; + case 3: outputTriplet(visit, "uint3(", "", ")"); break; + case 4: outputTriplet(visit, "uint4(", "", ")"); break; + default: UNREACHABLE(); + } + break; + case EOpRadians: outputTriplet(visit, "radians(", "", ")"); break; + case EOpDegrees: outputTriplet(visit, "degrees(", "", ")"); break; + case EOpSin: outputTriplet(visit, "sin(", "", ")"); break; + case EOpCos: outputTriplet(visit, "cos(", "", ")"); break; + case EOpTan: outputTriplet(visit, "tan(", "", ")"); break; + case EOpAsin: outputTriplet(visit, "asin(", "", ")"); break; + case EOpAcos: outputTriplet(visit, "acos(", "", ")"); break; + case EOpAtan: outputTriplet(visit, "atan(", "", ")"); break; + case EOpExp: outputTriplet(visit, "exp(", "", ")"); break; + case EOpLog: outputTriplet(visit, "log(", "", ")"); break; + case EOpExp2: outputTriplet(visit, "exp2(", "", ")"); break; + case EOpLog2: outputTriplet(visit, "log2(", "", ")"); break; + case EOpSqrt: outputTriplet(visit, "sqrt(", "", ")"); break; + case EOpInverseSqrt: outputTriplet(visit, "rsqrt(", "", ")"); break; + case EOpAbs: outputTriplet(visit, "abs(", "", ")"); break; + case EOpSign: outputTriplet(visit, "sign(", "", ")"); break; + case EOpFloor: outputTriplet(visit, "floor(", "", ")"); break; + case EOpCeil: outputTriplet(visit, "ceil(", "", ")"); break; + case EOpFract: outputTriplet(visit, "frac(", "", ")"); break; + case EOpLength: outputTriplet(visit, "length(", "", ")"); break; + case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break; + case EOpDFdx: + if(mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(visit, "ddx(", "", ")"); + } + break; + case EOpDFdy: + if(mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(visit, "ddy(", "", ")"); + } + break; + case EOpFwidth: + if(mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(visit, "fwidth(", "", ")"); + } + break; + case EOpAny: outputTriplet(visit, "any(", "", ")"); break; + case EOpAll: outputTriplet(visit, "all(", "", ")"); break; + default: UNREACHABLE(); + } + + return true; +} + +bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) +{ + TInfoSinkBase &out = mBody; + + switch (node->getOp()) + { + case EOpSequence: + { + if (mInsideFunction) + { + outputLineDirective(node->getLine().first_line); + out << "{\n"; + } + + for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++) + { + outputLineDirective((*sit)->getLine().first_line); + + traverseStatements(*sit); + + out << ";\n"; + } + + if (mInsideFunction) + { + outputLineDirective(node->getLine().last_line); + out << "}\n"; + } + + return false; + } + case EOpDeclaration: + if (visit == PreVisit) + { + TIntermSequence &sequence = node->getSequence(); + TIntermTyped *variable = sequence[0]->getAsTyped(); + + if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal)) + { + if (variable->getType().getStruct()) + { + addConstructor(variable->getType(), structNameString(*variable->getType().getStruct()), NULL); + } + + if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration + { + if (!mInsideFunction) + { + out << "static "; + } + + out << typeString(variable->getType()) + " "; + + for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) + { + TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); + + if (symbol) + { + symbol->traverse(this); + out << arrayString(symbol->getType()); + out << " = " + initializer(symbol->getType()); + } + else + { + (*sit)->traverse(this); + } + + if (*sit != sequence.back()) + { + out << ", "; + } + } + } + else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration + { + // Already added to constructor map + } + else UNREACHABLE(); + } + else if (variable && isVaryingOut(variable->getQualifier())) + { + for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) + { + TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); + + if (symbol) + { + // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking + mReferencedVaryings[symbol->getSymbol()] = symbol; + } + else + { + (*sit)->traverse(this); + } + } + } + + return false; + } + else if (visit == InVisit) + { + out << ", "; + } + break; + case EOpPrototype: + if (visit == PreVisit) + { + out << typeString(node->getType()) << " " << decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "("); + + TIntermSequence &arguments = node->getSequence(); + + for (unsigned int i = 0; i < arguments.size(); i++) + { + TIntermSymbol *symbol = arguments[i]->getAsSymbolNode(); + + if (symbol) + { + out << argumentString(symbol); + + if (i < arguments.size() - 1) + { + out << ", "; + } + } + else UNREACHABLE(); + } + + out << ");\n"; + + // Also prototype the Lod0 variant if needed + if (mContainsLoopDiscontinuity && !mOutputLod0Function) + { + mOutputLod0Function = true; + node->traverse(this); + mOutputLod0Function = false; + } + + return false; + } + break; + case EOpComma: outputTriplet(visit, "(", ", ", ")"); break; + case EOpFunction: + { + TString name = TFunction::unmangleName(node->getName()); + + out << typeString(node->getType()) << " "; + + if (name == "main") + { + out << "gl_main("; + } + else + { + out << decorate(name) << (mOutputLod0Function ? "Lod0(" : "("); + } + + TIntermSequence &sequence = node->getSequence(); + TIntermSequence &arguments = sequence[0]->getAsAggregate()->getSequence(); + + for (unsigned int i = 0; i < arguments.size(); i++) + { + TIntermSymbol *symbol = arguments[i]->getAsSymbolNode(); + + if (symbol) + { + if (symbol->getType().getStruct()) + { + addConstructor(symbol->getType(), structNameString(*symbol->getType().getStruct()), NULL); + } + + out << argumentString(symbol); + + if (i < arguments.size() - 1) + { + out << ", "; + } + } + else UNREACHABLE(); + } + + out << ")\n" + "{\n"; + + if (sequence.size() > 1) + { + mInsideFunction = true; + sequence[1]->traverse(this); + mInsideFunction = false; + } + + out << "}\n"; + + if (mContainsLoopDiscontinuity && !mOutputLod0Function) + { + if (name != "main") + { + mOutputLod0Function = true; + node->traverse(this); + mOutputLod0Function = false; + } + } + + return false; + } + break; + case EOpFunctionCall: + { + TString name = TFunction::unmangleName(node->getName()); + bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function; + TIntermSequence &arguments = node->getSequence(); + + if (node->isUserDefined()) + { + out << decorate(name) << (lod0 ? "Lod0(" : "("); + } + else + { + TBasicType samplerType = arguments[0]->getAsTyped()->getType().getBasicType(); + + TextureFunction textureFunction; + textureFunction.sampler = samplerType; + textureFunction.coords = arguments[1]->getAsTyped()->getNominalSize(); + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.proj = false; + textureFunction.offset = false; + + if (name == "texture2D" || name == "textureCube" || name == "texture") + { + textureFunction.method = TextureFunction::IMPLICIT; + } + else if (name == "texture2DProj" || name == "textureProj") + { + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.proj = true; + } + else if (name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod" || + name == "texture2DLodEXT" || name == "textureCubeLodEXT") + { + textureFunction.method = TextureFunction::LOD; + } + else if (name == "texture2DProjLod" || name == "textureProjLod" || name == "texture2DProjLodEXT") + { + textureFunction.method = TextureFunction::LOD; + textureFunction.proj = true; + } + else if (name == "textureSize") + { + textureFunction.method = TextureFunction::SIZE; + } + else if (name == "textureOffset") + { + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.offset = true; + } + else if (name == "textureProjOffset") + { + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.offset = true; + textureFunction.proj = true; + } + else if (name == "textureLodOffset") + { + textureFunction.method = TextureFunction::LOD; + textureFunction.offset = true; + } + else if (name == "textureProjLodOffset") + { + textureFunction.method = TextureFunction::LOD; + textureFunction.proj = true; + textureFunction.offset = true; + } + else if (name == "texelFetch") + { + textureFunction.method = TextureFunction::FETCH; + } + else if (name == "texelFetchOffset") + { + textureFunction.method = TextureFunction::FETCH; + textureFunction.offset = true; + } + else if (name == "textureGrad" || name == "texture2DGradEXT") + { + textureFunction.method = TextureFunction::GRAD; + } + else if (name == "textureGradOffset") + { + textureFunction.method = TextureFunction::GRAD; + textureFunction.offset = true; + } + else if (name == "textureProjGrad" || name == "texture2DProjGradEXT" || name == "textureCubeGradEXT") + { + textureFunction.method = TextureFunction::GRAD; + textureFunction.proj = true; + } + else if (name == "textureProjGradOffset") + { + textureFunction.method = TextureFunction::GRAD; + textureFunction.proj = true; + textureFunction.offset = true; + } + else UNREACHABLE(); + + if (textureFunction.method == TextureFunction::IMPLICIT) // Could require lod 0 or have a bias argument + { + unsigned int mandatoryArgumentCount = 2; // All functions have sampler and coordinate arguments + + if (textureFunction.offset) + { + mandatoryArgumentCount++; + } + + bool bias = (arguments.size() > mandatoryArgumentCount); // Bias argument is optional + + if (lod0 || mContext.shaderType == SH_VERTEX_SHADER) + { + if (bias) + { + textureFunction.method = TextureFunction::LOD0BIAS; + } + else + { + textureFunction.method = TextureFunction::LOD0; + } + } + else if (bias) + { + textureFunction.method = TextureFunction::BIAS; + } + } + + mUsesTexture.insert(textureFunction); + + out << textureFunction.name(); + } + + for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++) + { + if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType())) + { + out << "texture_"; + (*arg)->traverse(this); + out << ", sampler_"; + } + + (*arg)->traverse(this); + + if (arg < arguments.end() - 1) + { + out << ", "; + } + } + + out << ")"; + + return false; + } + break; + case EOpParameters: outputTriplet(visit, "(", ", ", ")\n{\n"); break; + case EOpConstructFloat: + addConstructor(node->getType(), "vec1", &node->getSequence()); + outputTriplet(visit, "vec1(", "", ")"); + break; + case EOpConstructVec2: + addConstructor(node->getType(), "vec2", &node->getSequence()); + outputTriplet(visit, "vec2(", ", ", ")"); + break; + case EOpConstructVec3: + addConstructor(node->getType(), "vec3", &node->getSequence()); + outputTriplet(visit, "vec3(", ", ", ")"); + break; + case EOpConstructVec4: + addConstructor(node->getType(), "vec4", &node->getSequence()); + outputTriplet(visit, "vec4(", ", ", ")"); + break; + case EOpConstructBool: + addConstructor(node->getType(), "bvec1", &node->getSequence()); + outputTriplet(visit, "bvec1(", "", ")"); + break; + case EOpConstructBVec2: + addConstructor(node->getType(), "bvec2", &node->getSequence()); + outputTriplet(visit, "bvec2(", ", ", ")"); + break; + case EOpConstructBVec3: + addConstructor(node->getType(), "bvec3", &node->getSequence()); + outputTriplet(visit, "bvec3(", ", ", ")"); + break; + case EOpConstructBVec4: + addConstructor(node->getType(), "bvec4", &node->getSequence()); + outputTriplet(visit, "bvec4(", ", ", ")"); + break; + case EOpConstructInt: + addConstructor(node->getType(), "ivec1", &node->getSequence()); + outputTriplet(visit, "ivec1(", "", ")"); + break; + case EOpConstructIVec2: + addConstructor(node->getType(), "ivec2", &node->getSequence()); + outputTriplet(visit, "ivec2(", ", ", ")"); + break; + case EOpConstructIVec3: + addConstructor(node->getType(), "ivec3", &node->getSequence()); + outputTriplet(visit, "ivec3(", ", ", ")"); + break; + case EOpConstructIVec4: + addConstructor(node->getType(), "ivec4", &node->getSequence()); + outputTriplet(visit, "ivec4(", ", ", ")"); + break; + case EOpConstructUInt: + addConstructor(node->getType(), "uvec1", &node->getSequence()); + outputTriplet(visit, "uvec1(", "", ")"); + break; + case EOpConstructUVec2: + addConstructor(node->getType(), "uvec2", &node->getSequence()); + outputTriplet(visit, "uvec2(", ", ", ")"); + break; + case EOpConstructUVec3: + addConstructor(node->getType(), "uvec3", &node->getSequence()); + outputTriplet(visit, "uvec3(", ", ", ")"); + break; + case EOpConstructUVec4: + addConstructor(node->getType(), "uvec4", &node->getSequence()); + outputTriplet(visit, "uvec4(", ", ", ")"); + break; + case EOpConstructMat2: + addConstructor(node->getType(), "mat2", &node->getSequence()); + outputTriplet(visit, "mat2(", ", ", ")"); + break; + case EOpConstructMat3: + addConstructor(node->getType(), "mat3", &node->getSequence()); + outputTriplet(visit, "mat3(", ", ", ")"); + break; + case EOpConstructMat4: + addConstructor(node->getType(), "mat4", &node->getSequence()); + outputTriplet(visit, "mat4(", ", ", ")"); + break; + case EOpConstructStruct: + { + const TString &structName = structNameString(*node->getType().getStruct()); + addConstructor(node->getType(), structName, &node->getSequence()); + outputTriplet(visit, structName + "_ctor(", ", ", ")"); + } + break; + case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; + case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; + case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break; + case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break; + case EOpVectorEqual: outputTriplet(visit, "(", " == ", ")"); break; + case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break; + case EOpMod: + { + // We need to look at the number of components in both arguments + const int modValue = node->getSequence()[0]->getAsTyped()->getNominalSize() * 10 + + node->getSequence()[1]->getAsTyped()->getNominalSize(); + switch (modValue) + { + case 11: mUsesMod1 = true; break; + case 22: mUsesMod2v = true; break; + case 21: mUsesMod2f = true; break; + case 33: mUsesMod3v = true; break; + case 31: mUsesMod3f = true; break; + case 44: mUsesMod4v = true; break; + case 41: mUsesMod4f = true; break; + default: UNREACHABLE(); + } + + outputTriplet(visit, "mod(", ", ", ")"); + } + break; + case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break; + case EOpAtan: + ASSERT(node->getSequence().size() == 2); // atan(x) is a unary operator + switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) + { + case 1: mUsesAtan2_1 = true; break; + case 2: mUsesAtan2_2 = true; break; + case 3: mUsesAtan2_3 = true; break; + case 4: mUsesAtan2_4 = true; break; + default: UNREACHABLE(); + } + outputTriplet(visit, "atanyx(", ", ", ")"); + break; + case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break; + case EOpMax: outputTriplet(visit, "max(", ", ", ")"); break; + case EOpClamp: outputTriplet(visit, "clamp(", ", ", ")"); break; + case EOpMix: outputTriplet(visit, "lerp(", ", ", ")"); break; + case EOpStep: outputTriplet(visit, "step(", ", ", ")"); break; + case EOpSmoothStep: outputTriplet(visit, "smoothstep(", ", ", ")"); break; + case EOpDistance: outputTriplet(visit, "distance(", ", ", ")"); break; + case EOpDot: outputTriplet(visit, "dot(", ", ", ")"); break; + case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break; + case EOpFaceForward: + { + switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument + { + case 1: mUsesFaceforward1 = true; break; + case 2: mUsesFaceforward2 = true; break; + case 3: mUsesFaceforward3 = true; break; + case 4: mUsesFaceforward4 = true; break; + default: UNREACHABLE(); + } + + outputTriplet(visit, "faceforward(", ", ", ")"); + } + break; + case EOpReflect: outputTriplet(visit, "reflect(", ", ", ")"); break; + case EOpRefract: outputTriplet(visit, "refract(", ", ", ")"); break; + case EOpMul: outputTriplet(visit, "(", " * ", ")"); break; + default: UNREACHABLE(); + } + + return true; +} + +bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) +{ + TInfoSinkBase &out = mBody; + + if (node->usesTernaryOperator()) + { + out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); + } + else // if/else statement + { + mUnfoldShortCircuit->traverse(node->getCondition()); + + out << "if ("; + + node->getCondition()->traverse(this); + + out << ")\n"; + + outputLineDirective(node->getLine().first_line); + out << "{\n"; + + bool discard = false; + + if (node->getTrueBlock()) + { + traverseStatements(node->getTrueBlock()); + + // Detect true discard + discard = (discard || FindDiscard::search(node->getTrueBlock())); + } + + outputLineDirective(node->getLine().first_line); + out << ";\n}\n"; + + if (node->getFalseBlock()) + { + out << "else\n"; + + outputLineDirective(node->getFalseBlock()->getLine().first_line); + out << "{\n"; + + outputLineDirective(node->getFalseBlock()->getLine().first_line); + traverseStatements(node->getFalseBlock()); + + outputLineDirective(node->getFalseBlock()->getLine().first_line); + out << ";\n}\n"; + + // Detect false discard + discard = (discard || FindDiscard::search(node->getFalseBlock())); + } + + // ANGLE issue 486: Detect problematic conditional discard + if (discard && FindSideEffectRewriting::search(node)) + { + mUsesDiscardRewriting = true; + } + } + + return false; +} + +void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node) +{ + writeConstantUnion(node->getType(), node->getUnionArrayPointer()); +} + +bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) +{ + mNestedLoopDepth++; + + bool wasDiscontinuous = mInsideDiscontinuousLoop; + + if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop) + { + mInsideDiscontinuousLoop = containsLoopDiscontinuity(node); + } + + if (mOutputType == SH_HLSL9_OUTPUT) + { + if (handleExcessiveLoop(node)) + { + mInsideDiscontinuousLoop = wasDiscontinuous; + mNestedLoopDepth--; + + return false; + } + } + + TInfoSinkBase &out = mBody; + + if (node->getType() == ELoopDoWhile) + { + out << "{do\n"; + + outputLineDirective(node->getLine().first_line); + out << "{\n"; + } + else + { + out << "{for("; + + if (node->getInit()) + { + node->getInit()->traverse(this); + } + + out << "; "; + + if (node->getCondition()) + { + node->getCondition()->traverse(this); + } + + out << "; "; + + if (node->getExpression()) + { + node->getExpression()->traverse(this); + } + + out << ")\n"; + + outputLineDirective(node->getLine().first_line); + out << "{\n"; + } + + if (node->getBody()) + { + traverseStatements(node->getBody()); + } + + outputLineDirective(node->getLine().first_line); + out << ";}\n"; + + if (node->getType() == ELoopDoWhile) + { + outputLineDirective(node->getCondition()->getLine().first_line); + out << "while(\n"; + + node->getCondition()->traverse(this); + + out << ");"; + } + + out << "}\n"; + + mInsideDiscontinuousLoop = wasDiscontinuous; + mNestedLoopDepth--; + + return false; +} + +bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) +{ + TInfoSinkBase &out = mBody; + + switch (node->getFlowOp()) + { + case EOpKill: + outputTriplet(visit, "discard;\n", "", ""); + break; + case EOpBreak: + if (visit == PreVisit) + { + if (mNestedLoopDepth > 1) + { + mUsesNestedBreak = true; + } + + if (mExcessiveLoopIndex) + { + out << "{Break"; + mExcessiveLoopIndex->traverse(this); + out << " = true; break;}\n"; + } + else + { + out << "break;\n"; + } + } + break; + case EOpContinue: outputTriplet(visit, "continue;\n", "", ""); break; + case EOpReturn: + if (visit == PreVisit) + { + if (node->getExpression()) + { + out << "return "; + } + else + { + out << "return;\n"; + } + } + else if (visit == PostVisit) + { + if (node->getExpression()) + { + out << ";\n"; + } + } + break; + default: UNREACHABLE(); + } + + return true; +} + +void OutputHLSL::traverseStatements(TIntermNode *node) +{ + if (isSingleStatement(node)) + { + mUnfoldShortCircuit->traverse(node); + } + + node->traverse(this); +} + +bool OutputHLSL::isSingleStatement(TIntermNode *node) +{ + TIntermAggregate *aggregate = node->getAsAggregate(); + + if (aggregate) + { + if (aggregate->getOp() == EOpSequence) + { + return false; + } + else + { + for (TIntermSequence::iterator sit = aggregate->getSequence().begin(); sit != aggregate->getSequence().end(); sit++) + { + if (!isSingleStatement(*sit)) + { + return false; + } + } + + return true; + } + } + + return true; +} + +// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them +// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254). +bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) +{ + const int MAX_LOOP_ITERATIONS = 254; + TInfoSinkBase &out = mBody; + + // Parse loops of the form: + // for(int index = initial; index [comparator] limit; index += increment) + TIntermSymbol *index = NULL; + TOperator comparator = EOpNull; + int initial = 0; + int limit = 0; + int increment = 0; + + // Parse index name and intial value + if (node->getInit()) + { + TIntermAggregate *init = node->getInit()->getAsAggregate(); + + if (init) + { + TIntermSequence &sequence = init->getSequence(); + TIntermTyped *variable = sequence[0]->getAsTyped(); + + if (variable && variable->getQualifier() == EvqTemporary) + { + TIntermBinary *assign = variable->getAsBinaryNode(); + + if (assign->getOp() == EOpInitialize) + { + TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode(); + TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion(); + + if (symbol && constant) + { + if (constant->getBasicType() == EbtInt && constant->isScalar()) + { + index = symbol; + initial = constant->getIConst(0); + } + } + } + } + } + } + + // Parse comparator and limit value + if (index != NULL && node->getCondition()) + { + TIntermBinary *test = node->getCondition()->getAsBinaryNode(); + + if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId()) + { + TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion(); + + if (constant) + { + if (constant->getBasicType() == EbtInt && constant->isScalar()) + { + comparator = test->getOp(); + limit = constant->getIConst(0); + } + } + } + } + + // Parse increment + if (index != NULL && comparator != EOpNull && node->getExpression()) + { + TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode(); + TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode(); + + if (binaryTerminal) + { + TOperator op = binaryTerminal->getOp(); + TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion(); + + if (constant) + { + if (constant->getBasicType() == EbtInt && constant->isScalar()) + { + int value = constant->getIConst(0); + + switch (op) + { + case EOpAddAssign: increment = value; break; + case EOpSubAssign: increment = -value; break; + default: UNIMPLEMENTED(); + } + } + } + } + else if (unaryTerminal) + { + TOperator op = unaryTerminal->getOp(); + + switch (op) + { + case EOpPostIncrement: increment = 1; break; + case EOpPostDecrement: increment = -1; break; + case EOpPreIncrement: increment = 1; break; + case EOpPreDecrement: increment = -1; break; + default: UNIMPLEMENTED(); + } + } + } + + if (index != NULL && comparator != EOpNull && increment != 0) + { + if (comparator == EOpLessThanEqual) + { + comparator = EOpLessThan; + limit += 1; + } + + if (comparator == EOpLessThan) + { + int iterations = (limit - initial) / increment; + + if (iterations <= MAX_LOOP_ITERATIONS) + { + return false; // Not an excessive loop + } + + TIntermSymbol *restoreIndex = mExcessiveLoopIndex; + mExcessiveLoopIndex = index; + + out << "{int "; + index->traverse(this); + out << ";\n" + "bool Break"; + index->traverse(this); + out << " = false;\n"; + + bool firstLoopFragment = true; + + while (iterations > 0) + { + int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations); + + if (!firstLoopFragment) + { + out << "if (!Break"; + index->traverse(this); + out << ") {\n"; + } + + if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment + { + mExcessiveLoopIndex = NULL; // Stops setting the Break flag + } + + // for(int index = initial; index < clampedLimit; index += increment) + + out << "for("; + index->traverse(this); + out << " = "; + out << initial; + + out << "; "; + index->traverse(this); + out << " < "; + out << clampedLimit; + + out << "; "; + index->traverse(this); + out << " += "; + out << increment; + out << ")\n"; + + outputLineDirective(node->getLine().first_line); + out << "{\n"; + + if (node->getBody()) + { + node->getBody()->traverse(this); + } + + outputLineDirective(node->getLine().first_line); + out << ";}\n"; + + if (!firstLoopFragment) + { + out << "}\n"; + } + + firstLoopFragment = false; + + initial += MAX_LOOP_ITERATIONS * increment; + iterations -= MAX_LOOP_ITERATIONS; + } + + out << "}"; + + mExcessiveLoopIndex = restoreIndex; + + return true; + } + else UNIMPLEMENTED(); + } + + return false; // Not handled as an excessive loop +} + +void OutputHLSL::outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString) +{ + TInfoSinkBase &out = mBody; + + if (visit == PreVisit) + { + out << preString; + } + else if (visit == InVisit) + { + out << inString; + } + else if (visit == PostVisit) + { + out << postString; + } +} + +void OutputHLSL::outputLineDirective(int line) +{ + if ((mContext.compileOptions & SH_LINE_DIRECTIVES) && (line > 0)) + { + mBody << "\n"; + mBody << "#line " << line; + + if (mContext.sourcePath) + { + mBody << " \"" << mContext.sourcePath << "\""; + } + + mBody << "\n"; + } +} + +TString OutputHLSL::argumentString(const TIntermSymbol *symbol) +{ + TQualifier qualifier = symbol->getQualifier(); + const TType &type = symbol->getType(); + TString name = symbol->getSymbol(); + + if (name.empty()) // HLSL demands named arguments, also for prototypes + { + name = "x" + str(mUniqueIndex++); + } + else + { + name = decorate(name); + } + + if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) + { + return qualifierString(qualifier) + " " + textureString(type) + " texture_" + name + arrayString(type) + ", " + + qualifierString(qualifier) + " " + samplerString(type) + " sampler_" + name + arrayString(type); + } + + return qualifierString(qualifier) + " " + typeString(type) + " " + name + arrayString(type); +} + +TString OutputHLSL::interpolationString(TQualifier qualifier) +{ + switch(qualifier) + { + case EvqVaryingIn: return ""; + case EvqFragmentIn: return ""; + case EvqInvariantVaryingIn: return ""; + case EvqSmoothIn: return "linear"; + case EvqFlatIn: return "nointerpolation"; + case EvqCentroidIn: return "centroid"; + case EvqVaryingOut: return ""; + case EvqVertexOut: return ""; + case EvqInvariantVaryingOut: return ""; + case EvqSmoothOut: return "linear"; + case EvqFlatOut: return "nointerpolation"; + case EvqCentroidOut: return "centroid"; + default: UNREACHABLE(); + } + + return ""; +} + +TString OutputHLSL::qualifierString(TQualifier qualifier) +{ + switch(qualifier) + { + case EvqIn: return "in"; + case EvqOut: return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined + case EvqInOut: return "inout"; + case EvqConstReadOnly: return "const"; + default: UNREACHABLE(); + } + + return ""; +} + +TString OutputHLSL::typeString(const TType &type) +{ + const TStructure* structure = type.getStruct(); + if (structure) + { + const TString& typeName = structure->name(); + if (typeName != "") + { + return structNameString(*type.getStruct()); + } + else // Nameless structure, define in place + { + return structureString(*structure, false, false); + } + } + else if (type.isMatrix()) + { + int cols = type.getCols(); + int rows = type.getRows(); + return "float" + str(cols) + "x" + str(rows); + } + else + { + switch (type.getBasicType()) + { + case EbtFloat: + switch (type.getNominalSize()) + { + case 1: return "float"; + case 2: return "float2"; + case 3: return "float3"; + case 4: return "float4"; + } + case EbtInt: + switch (type.getNominalSize()) + { + case 1: return "int"; + case 2: return "int2"; + case 3: return "int3"; + case 4: return "int4"; + } + case EbtUInt: + switch (type.getNominalSize()) + { + case 1: return "uint"; + case 2: return "uint2"; + case 3: return "uint3"; + case 4: return "uint4"; + } + case EbtBool: + switch (type.getNominalSize()) + { + case 1: return "bool"; + case 2: return "bool2"; + case 3: return "bool3"; + case 4: return "bool4"; + } + case EbtVoid: + return "void"; + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + return "sampler2D"; + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + return "samplerCUBE"; + case EbtSamplerExternalOES: + return "sampler2D"; + default: + break; + } + } + + UNREACHABLE(); + return "<unknown type>"; +} + +TString OutputHLSL::textureString(const TType &type) +{ + switch (type.getBasicType()) + { + case EbtSampler2D: return "Texture2D"; + case EbtSamplerCube: return "TextureCube"; + case EbtSamplerExternalOES: return "Texture2D"; + case EbtSampler2DArray: return "Texture2DArray"; + case EbtSampler3D: return "Texture3D"; + case EbtISampler2D: return "Texture2D<int4>"; + case EbtISampler3D: return "Texture3D<int4>"; + case EbtISamplerCube: return "Texture2DArray<int4>"; + case EbtISampler2DArray: return "Texture2DArray<int4>"; + case EbtUSampler2D: return "Texture2D<uint4>"; + case EbtUSampler3D: return "Texture3D<uint4>"; + case EbtUSamplerCube: return "Texture2DArray<uint4>"; + case EbtUSampler2DArray: return "Texture2DArray<uint4>"; + case EbtSampler2DShadow: return "Texture2D"; + case EbtSamplerCubeShadow: return "TextureCube"; + case EbtSampler2DArrayShadow: return "Texture2DArray"; + default: UNREACHABLE(); + } + + return "<unknown texture type>"; +} + +TString OutputHLSL::samplerString(const TType &type) +{ + if (IsShadowSampler(type.getBasicType())) + { + return "SamplerComparisonState"; + } + else + { + return "SamplerState"; + } +} + +TString OutputHLSL::arrayString(const TType &type) +{ + if (!type.isArray()) + { + return ""; + } + + return "[" + str(type.getArraySize()) + "]"; +} + +TString OutputHLSL::initializer(const TType &type) +{ + TString string; + + size_t size = type.getObjectSize(); + for (size_t component = 0; component < size; component++) + { + string += "0"; + + if (component + 1 < size) + { + string += ", "; + } + } + + return "{" + string + "}"; +} + +TString OutputHLSL::structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing) +{ + const TFieldList &fields = structure.fields(); + const bool isNameless = (structure.name() == ""); + const TString &structName = structureTypeName(structure, useHLSLRowMajorPacking, useStd140Packing); + const TString declareString = (isNameless ? "struct" : "struct " + structName); + + TString string; + string += declareString + "\n" + "{\n"; + + int elementIndex = 0; + + for (unsigned int i = 0; i < fields.size(); i++) + { + const TField &field = *fields[i]; + const TType &fieldType = *field.type(); + const TStructure *fieldStruct = fieldType.getStruct(); + const TString &fieldTypeString = fieldStruct ? structureTypeName(*fieldStruct, useHLSLRowMajorPacking, useStd140Packing) : typeString(fieldType); + + if (useStd140Packing) + { + string += std140PrePaddingString(*field.type(), &elementIndex); + } + + string += " " + fieldTypeString + " " + decorateField(field.name(), structure) + arrayString(fieldType) + ";\n"; + + if (useStd140Packing) + { + string += std140PostPaddingString(*field.type(), useHLSLRowMajorPacking); + } + } + + // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable + string += (isNameless ? "} " : "};\n"); + + // Add remaining element index to the global map, for use with nested structs in standard layouts + if (useStd140Packing) + { + mStd140StructElementIndexes[structName] = elementIndex; + } + + return string; +} + +TString OutputHLSL::structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing) +{ + if (structure.name() == "") + { + return ""; + } + + TString prefix = ""; + + // Structs packed with row-major matrices in HLSL are prefixed with "rm" + // GLSL column-major maps to HLSL row-major, and the converse is true + + if (useStd140Packing) + { + prefix += "std"; + } + + if (useHLSLRowMajorPacking) + { + if (prefix != "") prefix += "_"; + prefix += "rm"; + } + + return prefix + structNameString(structure); +} + +void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) +{ + if (name == "") + { + return; // Nameless structures don't have constructors + } + + if (type.getStruct() && mStructNames.find(name) != mStructNames.end()) + { + return; // Already added + } + + TType ctorType = type; + ctorType.clearArrayness(); + ctorType.setPrecision(EbpHigh); + ctorType.setQualifier(EvqTemporary); + + typedef std::vector<TType> ParameterArray; + ParameterArray ctorParameters; + + const TStructure* structure = type.getStruct(); + if (structure) + { + mStructNames.insert(name); + + const TString &structString = structureString(*structure, false, false); + + if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end()) + { + // Add row-major packed struct for interface blocks + TString rowMajorString = "#pragma pack_matrix(row_major)\n" + + structureString(*structure, true, false) + + "#pragma pack_matrix(column_major)\n"; + + TString std140String = structureString(*structure, false, true); + TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + + structureString(*structure, true, true) + + "#pragma pack_matrix(column_major)\n"; + + mStructDeclarations.push_back(structString); + mStructDeclarations.push_back(rowMajorString); + mStructDeclarations.push_back(std140String); + mStructDeclarations.push_back(std140RowMajorString); + } + + const TFieldList &fields = structure->fields(); + for (unsigned int i = 0; i < fields.size(); i++) + { + ctorParameters.push_back(*fields[i]->type()); + } + } + else if (parameters) + { + for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) + { + ctorParameters.push_back((*parameter)->getAsTyped()->getType()); + } + } + else UNREACHABLE(); + + TString constructor; + + if (ctorType.getStruct()) + { + constructor += name + " " + name + "_ctor("; + } + else // Built-in type + { + constructor += typeString(ctorType) + " " + name + "("; + } + + for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++) + { + const TType &type = ctorParameters[parameter]; + + constructor += typeString(type) + " x" + str(parameter) + arrayString(type); + + if (parameter < ctorParameters.size() - 1) + { + constructor += ", "; + } + } + + constructor += ")\n" + "{\n"; + + if (ctorType.getStruct()) + { + constructor += " " + name + " structure = {"; + } + else + { + constructor += " return " + typeString(ctorType) + "("; + } + + if (ctorType.isMatrix() && ctorParameters.size() == 1) + { + int rows = ctorType.getRows(); + int cols = ctorType.getCols(); + const TType ¶meter = ctorParameters[0]; + + if (parameter.isScalar()) + { + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { + constructor += TString((row == col) ? "x0" : "0.0"); + + if (row < rows - 1 || col < cols - 1) + { + constructor += ", "; + } + } + } + } + else if (parameter.isMatrix()) + { + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { + if (row < parameter.getRows() && col < parameter.getCols()) + { + constructor += TString("x0") + "[" + str(row) + "]" + "[" + str(col) + "]"; + } + else + { + constructor += TString((row == col) ? "1.0" : "0.0"); + } + + if (row < rows - 1 || col < cols - 1) + { + constructor += ", "; + } + } + } + } + else UNREACHABLE(); + } + else + { + size_t remainingComponents = ctorType.getObjectSize(); + size_t parameterIndex = 0; + + while (remainingComponents > 0) + { + const TType ¶meter = ctorParameters[parameterIndex]; + const size_t parameterSize = parameter.getObjectSize(); + bool moreParameters = parameterIndex + 1 < ctorParameters.size(); + + constructor += "x" + str(parameterIndex); + + if (parameter.isScalar()) + { + remainingComponents -= parameter.getObjectSize(); + } + else if (parameter.isVector()) + { + if (remainingComponents == parameterSize || moreParameters) + { + ASSERT(parameterSize <= remainingComponents); + remainingComponents -= parameterSize; + } + else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize())) + { + switch (remainingComponents) + { + case 1: constructor += ".x"; break; + case 2: constructor += ".xy"; break; + case 3: constructor += ".xyz"; break; + case 4: constructor += ".xyzw"; break; + default: UNREACHABLE(); + } + + remainingComponents = 0; + } + else UNREACHABLE(); + } + else if (parameter.isMatrix() || parameter.getStruct()) + { + ASSERT(remainingComponents == parameterSize || moreParameters); + ASSERT(parameterSize <= remainingComponents); + + remainingComponents -= parameterSize; + } + else UNREACHABLE(); + + if (moreParameters) + { + parameterIndex++; + } + + if (remainingComponents) + { + constructor += ", "; + } + } + } + + if (ctorType.getStruct()) + { + constructor += "};\n" + " return structure;\n" + "}\n"; + } + else + { + constructor += ");\n" + "}\n"; + } + + mConstructors.insert(constructor); +} + +const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const ConstantUnion *constUnion) +{ + TInfoSinkBase &out = mBody; + + const TStructure* structure = type.getStruct(); + if (structure) + { + out << structNameString(*structure) + "_ctor("; + + const TFieldList& fields = structure->fields(); + + for (size_t i = 0; i < fields.size(); i++) + { + const TType *fieldType = fields[i]->type(); + + constUnion = writeConstantUnion(*fieldType, constUnion); + + if (i != fields.size() - 1) + { + out << ", "; + } + } + + out << ")"; + } + else + { + size_t size = type.getObjectSize(); + bool writeType = size > 1; + + if (writeType) + { + out << typeString(type) << "("; + } + + for (size_t i = 0; i < size; i++, constUnion++) + { + switch (constUnion->getType()) + { + case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); break; + case EbtInt: out << constUnion->getIConst(); break; + case EbtUInt: out << constUnion->getUConst(); break; + case EbtBool: out << constUnion->getBConst(); break; + default: UNREACHABLE(); + } + + if (i != size - 1) + { + out << ", "; + } + } + + if (writeType) + { + out << ")"; + } + } + + return constUnion; +} + +TString OutputHLSL::structNameString(const TStructure &structure) +{ + if (structure.name().empty()) + { + return ""; + } + + return "ss_" + str(structure.uniqueId()) + structure.name(); +} + +TString OutputHLSL::decorate(const TString &string) +{ + if (string.compare(0, 3, "gl_") != 0 && string.compare(0, 3, "dx_") != 0) + { + return "_" + string; + } + + return string; +} + +TString OutputHLSL::decorateUniform(const TString &string, const TType &type) +{ + if (type.getBasicType() == EbtSamplerExternalOES) + { + return "ex_" + string; + } + + return decorate(string); +} + +TString OutputHLSL::decorateField(const TString &string, const TStructure &structure) +{ + if (structure.name().compare(0, 3, "gl_") != 0) + { + return decorate(string); + } + + return string; +} + +void OutputHLSL::declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output) +{ + const TStructure *structure = type.getStruct(); + + if (!structure) + { + const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor); + gl::InterfaceBlockField field(glVariableType(type), glVariablePrecision(type), name.c_str(), + (unsigned int)type.getArraySize(), isRowMajorMatrix); + output.push_back(field); + } + else + { + gl::InterfaceBlockField structField(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), false); + + const TFieldList &fields = structure->fields(); + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + { + TField *field = fields[fieldIndex]; + TType *fieldType = field->type(); + + // make sure to copy matrix packing information + fieldType->setLayoutQualifier(type.getLayoutQualifier()); + + declareInterfaceBlockField(*fieldType, field->name(), structField.fields); + } + + output.push_back(structField); + } +} + +gl::Uniform OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output) +{ + const TStructure *structure = type.getStruct(); + + if (!structure) + { + gl::Uniform uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), + (unsigned int)type.getArraySize(), (unsigned int)registerIndex, 0); + output.push_back(uniform); + + return uniform; + } + else + { + gl::Uniform structUniform(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), + (unsigned int)registerIndex, GL_INVALID_INDEX); + + const TFieldList &fields = structure->fields(); + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + { + TField *field = fields[fieldIndex]; + TType *fieldType = field->type(); + + declareUniformToList(*fieldType, field->name(), GL_INVALID_INDEX, structUniform.fields); + } + + // assign register offset information -- this will override the information in any sub-structures. + HLSLVariableGetRegisterInfo(registerIndex, &structUniform, mOutputType); + + output.push_back(structUniform); + + return structUniform; + } +} + +gl::InterpolationType getInterpolationType(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqFlatIn: + case EvqFlatOut: + return gl::INTERPOLATION_FLAT; + + case EvqSmoothIn: + case EvqSmoothOut: + case EvqVertexOut: + case EvqFragmentIn: + case EvqVaryingIn: + case EvqVaryingOut: + return gl::INTERPOLATION_SMOOTH; + + case EvqCentroidIn: + case EvqCentroidOut: + return gl::INTERPOLATION_CENTROID; + + default: UNREACHABLE(); + return gl::INTERPOLATION_SMOOTH; + } +} + +void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut) +{ + const TStructure *structure = type.getStruct(); + + gl::InterpolationType interpolation = getInterpolationType(baseTypeQualifier); + if (!structure) + { + gl::Varying varying(glVariableType(type), glVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), interpolation); + fieldsOut.push_back(varying); + } + else + { + gl::Varying structVarying(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), interpolation); + const TFieldList &fields = structure->fields(); + + structVarying.structName = structure->name().c_str(); + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + { + const TField &field = *fields[fieldIndex]; + declareVaryingToList(*field.type(), baseTypeQualifier, field.name(), structVarying.fields); + } + + fieldsOut.push_back(structVarying); + } +} + +int OutputHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name) +{ + int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister); + + const gl::Uniform &uniform = declareUniformToList(type, name, registerIndex, mActiveUniforms); + + if (IsSampler(type.getBasicType())) + { + mSamplerRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType); + } + else + { + mUniformRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType); + } + + return registerIndex; +} + +GLenum OutputHLSL::glVariableType(const TType &type) +{ + if (type.getBasicType() == EbtFloat) + { + if (type.isScalar()) + { + return GL_FLOAT; + } + else if (type.isVector()) + { + switch(type.getNominalSize()) + { + case 2: return GL_FLOAT_VEC2; + case 3: return GL_FLOAT_VEC3; + case 4: return GL_FLOAT_VEC4; + default: UNREACHABLE(); + } + } + else if (type.isMatrix()) + { + switch (type.getCols()) + { + case 2: + switch(type.getRows()) + { + case 2: return GL_FLOAT_MAT2; + case 3: return GL_FLOAT_MAT2x3; + case 4: return GL_FLOAT_MAT2x4; + default: UNREACHABLE(); + } + + case 3: + switch(type.getRows()) + { + case 2: return GL_FLOAT_MAT3x2; + case 3: return GL_FLOAT_MAT3; + case 4: return GL_FLOAT_MAT3x4; + default: UNREACHABLE(); + } + + case 4: + switch(type.getRows()) + { + case 2: return GL_FLOAT_MAT4x2; + case 3: return GL_FLOAT_MAT4x3; + case 4: return GL_FLOAT_MAT4; + default: UNREACHABLE(); + } + + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + } + else if (type.getBasicType() == EbtInt) + { + if (type.isScalar()) + { + return GL_INT; + } + else if (type.isVector()) + { + switch(type.getNominalSize()) + { + case 2: return GL_INT_VEC2; + case 3: return GL_INT_VEC3; + case 4: return GL_INT_VEC4; + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + } + else if (type.getBasicType() == EbtUInt) + { + if (type.isScalar()) + { + return GL_UNSIGNED_INT; + } + else if (type.isVector()) + { + switch(type.getNominalSize()) + { + case 2: return GL_UNSIGNED_INT_VEC2; + case 3: return GL_UNSIGNED_INT_VEC3; + case 4: return GL_UNSIGNED_INT_VEC4; + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + } + else if (type.getBasicType() == EbtBool) + { + if (type.isScalar()) + { + return GL_BOOL; + } + else if (type.isVector()) + { + switch(type.getNominalSize()) + { + case 2: return GL_BOOL_VEC2; + case 3: return GL_BOOL_VEC3; + case 4: return GL_BOOL_VEC4; + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + } + + switch(type.getBasicType()) + { + case EbtSampler2D: return GL_SAMPLER_2D; + case EbtSampler3D: return GL_SAMPLER_3D; + case EbtSamplerCube: return GL_SAMPLER_CUBE; + case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY; + case EbtISampler2D: return GL_INT_SAMPLER_2D; + case EbtISampler3D: return GL_INT_SAMPLER_3D; + case EbtISamplerCube: return GL_INT_SAMPLER_CUBE; + case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY; + case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D; + case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D; + case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE; + case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; + case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW; + case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW; + case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW; + default: UNREACHABLE(); + } + + return GL_NONE; +} + +GLenum OutputHLSL::glVariablePrecision(const TType &type) +{ + if (type.getBasicType() == EbtFloat) + { + switch (type.getPrecision()) + { + case EbpHigh: return GL_HIGH_FLOAT; + case EbpMedium: return GL_MEDIUM_FLOAT; + case EbpLow: return GL_LOW_FLOAT; + case EbpUndefined: + // Should be defined as the default precision by the parser + default: UNREACHABLE(); + } + } + else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt) + { + switch (type.getPrecision()) + { + case EbpHigh: return GL_HIGH_INT; + case EbpMedium: return GL_MEDIUM_INT; + case EbpLow: return GL_LOW_INT; + case EbpUndefined: + // Should be defined as the default precision by the parser + default: UNREACHABLE(); + } + } + + // Other types (boolean, sampler) don't have a precision + return GL_NONE; +} + +bool OutputHLSL::isVaryingOut(TQualifier qualifier) +{ + switch(qualifier) + { + case EvqVaryingOut: + case EvqInvariantVaryingOut: + case EvqSmoothOut: + case EvqFlatOut: + case EvqCentroidOut: + case EvqVertexOut: + return true; + + default: break; + } + + return false; +} + +bool OutputHLSL::isVaryingIn(TQualifier qualifier) +{ + switch(qualifier) + { + case EvqVaryingIn: + case EvqInvariantVaryingIn: + case EvqSmoothIn: + case EvqFlatIn: + case EvqCentroidIn: + case EvqFragmentIn: + return true; + + default: break; + } + + return false; +} + +bool OutputHLSL::isVarying(TQualifier qualifier) +{ + return isVaryingIn(qualifier) || isVaryingOut(qualifier); +} + +} diff --git a/chromium/third_party/angle/src/compiler/OutputHLSL.h b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.h index 586a76fb9c7..ab5a90be6e6 100644 --- a/chromium/third_party/angle/src/compiler/OutputHLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,12 +11,12 @@ #include <set> #include <map> -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> -#include "compiler/intermediate.h" -#include "compiler/ParseContext.h" -#include "compiler/Uniform.h" +#include "compiler/translator/intermediate.h" +#include "compiler/translator/ParseContext.h" +#include "common/shadervars.h" namespace sh { @@ -31,22 +31,31 @@ class OutputHLSL : public TIntermTraverser void output(); TInfoSinkBase &getBodyStream(); - const ActiveUniforms &getUniforms(); + const std::vector<gl::Uniform> &getUniforms(); + const std::vector<gl::InterfaceBlock> &getInterfaceBlocks() const; + const std::vector<gl::Attribute> &getOutputVariables() const; + const std::vector<gl::Attribute> &getAttributes() const; + const std::vector<gl::Varying> &getVaryings() const; TString typeString(const TType &type); TString textureString(const TType &type); + TString samplerString(const TType &type); + TString interpolationString(TQualifier qualifier); + TString structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing); + TString structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing); static TString qualifierString(TQualifier qualifier); static TString arrayString(const TType &type); static TString initializer(const TType &type); static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes static TString decorateUniform(const TString &string, const TType &type); - static TString decorateField(const TString &string, const TType &structure); + static TString decorateField(const TString &string, const TStructure &structure); protected: void header(); // Visit AST nodes and output their code to the body stream void visitSymbol(TIntermSymbol*); + void visitRaw(TIntermRaw*); void visitConstantUnion(TIntermConstantUnion*); bool visitBinary(Visit visit, TIntermBinary*); bool visitUnary(Visit visit, TIntermUnary*); @@ -66,9 +75,7 @@ class OutputHLSL : public TIntermTraverser void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters); const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion); - TString scopeString(unsigned int depthLimit); - TString scopedStruct(const TString &typeName); - TString structLookup(const TString &typeName); + TString structNameString(const TStructure &structure); TParseContext &mContext; const ShShaderOutput mOutputType; @@ -82,25 +89,40 @@ class OutputHLSL : public TIntermTraverser typedef std::map<TString, TIntermSymbol*> ReferencedSymbols; ReferencedSymbols mReferencedUniforms; + ReferencedSymbols mReferencedInterfaceBlocks; ReferencedSymbols mReferencedAttributes; ReferencedSymbols mReferencedVaryings; + ReferencedSymbols mReferencedOutputVariables; + + struct TextureFunction + { + enum Method + { + IMPLICIT, // Mipmap LOD determined implicitly (standard lookup) + BIAS, + LOD, + LOD0, + LOD0BIAS, + SIZE, // textureSize() + FETCH, + GRAD + }; + + TBasicType sampler; + int coords; + bool proj; + bool offset; + Method method; + + TString name() const; + + bool operator<(const TextureFunction &rhs) const; + }; + + typedef std::set<TextureFunction> TextureFunctionSet; // Parameters determining what goes in the header output - bool mUsesTexture2D; - bool mUsesTexture2D_bias; - bool mUsesTexture2DLod; - bool mUsesTexture2DProj; - bool mUsesTexture2DProj_bias; - bool mUsesTexture2DProjLod; - bool mUsesTextureCube; - bool mUsesTextureCube_bias; - bool mUsesTextureCubeLod; - bool mUsesTexture2DLod0; - bool mUsesTexture2DLod0_bias; - bool mUsesTexture2DProjLod0; - bool mUsesTexture2DProjLod0_bias; - bool mUsesTextureCubeLod0; - bool mUsesTextureCubeLod0_bias; + TextureFunctionSet mUsesTexture; bool mUsesFragColor; bool mUsesFragData; bool mUsesDepthRange; @@ -126,6 +148,7 @@ class OutputHLSL : public TIntermTraverser bool mUsesAtan2_3; bool mUsesAtan2_4; bool mUsesDiscardRewriting; + bool mUsesNestedBreak; int mNumRenderTargets; @@ -138,29 +161,59 @@ class OutputHLSL : public TIntermTraverser typedef std::list<TString> StructDeclarations; StructDeclarations mStructDeclarations; - typedef std::vector<int> ScopeBracket; - ScopeBracket mScopeBracket; - unsigned int mScopeDepth; - int mUniqueIndex; // For creating unique names bool mContainsLoopDiscontinuity; bool mOutputLod0Function; bool mInsideDiscontinuousLoop; + int mNestedLoopDepth; TIntermSymbol *mExcessiveLoopIndex; int mUniformRegister; + int mInterfaceBlockRegister; int mSamplerRegister; + int mPaddingCounter; TString registerString(TIntermSymbol *operand); int samplerRegister(TIntermSymbol *sampler); int uniformRegister(TIntermSymbol *uniform); + void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output); + gl::Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output); void declareUniform(const TType &type, const TString &name, int index); + void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut); + + // Returns the uniform's register index + int declareUniformAndAssignRegister(const TType &type, const TString &name); + + TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field); + TString decoratePrivate(const TString &privateText); + TString interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlockType); + TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex); + TString interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage); + TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage); + TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock); + TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex); + TString std140PrePaddingString(const TType &type, int *elementIndex); + TString std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking); + TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName); + static GLenum glVariableType(const TType &type); static GLenum glVariablePrecision(const TType &type); - - ActiveUniforms mActiveUniforms; + static bool isVaryingIn(TQualifier qualifier); + static bool isVaryingOut(TQualifier qualifier); + static bool isVarying(TQualifier qualifier); + + std::vector<gl::Uniform> mActiveUniforms; + std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks; + std::vector<gl::Attribute> mActiveOutputVariables; + std::vector<gl::Attribute> mActiveAttributes; + std::vector<gl::Varying> mActiveVaryings; + std::map<TString, int> mStd140StructElementIndexes; + std::map<TIntermTyped*, TString> mFlaggedStructMappedNames; + std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames; + + void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs); }; } diff --git a/chromium/third_party/angle/src/compiler/ParseContext.cpp b/chromium/third_party/angle/src/compiler/translator/ParseContext.cpp index 4db9c0346e5..f9009668b02 100644 --- a/chromium/third_party/angle/src/compiler/ParseContext.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ParseContext.cpp @@ -4,12 +4,12 @@ // found in the LICENSE file. // -#include "compiler/ParseContext.h" +#include "compiler/translator/ParseContext.h" #include <stdarg.h> #include <stdio.h> -#include "compiler/glslang.h" +#include "compiler/translator/glslang.h" #include "compiler/preprocessor/SourceLocation.h" /////////////////////////////////////////////////////////////////////// @@ -115,7 +115,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV // Look at a '.' field selector string and change it into offsets // for a matrix. // -bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, const TSourceLoc& line) +bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc& line) { fields.wholeRow = false; fields.wholeCol = false; @@ -151,7 +151,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM fields.col = compString[1] - '0'; } - if (fields.row >= matSize || fields.col >= matSize) { + if (fields.row >= matRows || fields.col >= matCols) { error(line, "matrix field selection out of range", compString.c_str()); return false; } @@ -277,6 +277,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIn case EOpIndexDirect: case EOpIndexIndirect: case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: return lValueErrorCheck(line, op, binaryNode->getLeft()); case EOpVectorSwizzle: errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); @@ -317,6 +318,8 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIn case EvqConst: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break; case EvqAttribute: message = "can't modify an attribute"; break; + case EvqFragmentIn: message = "can't modify an input"; break; + case EvqVertexIn: message = "can't modify an input"; break; case EvqUniform: message = "can't modify a uniform"; break; case EvqVaryingIn: message = "can't modify a varying"; break; case EvqFragCoord: message = "can't modify gl_FragCoord"; break; @@ -327,16 +330,11 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIn // // Type that can't be written to? // - switch (node->getBasicType()) { - case EbtSampler2D: - case EbtSamplerCube: - message = "can't modify a sampler"; - break; - case EbtVoid: + if (node->getBasicType() == EbtVoid) { message = "can't modify void"; - break; - default: - break; + } + if (IsSampler(node->getBasicType())) { + message = "can't modify a sampler"; } } @@ -396,7 +394,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node) // bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) { - if (node->getBasicType() == EbtInt && node->getNominalSize() == 1) + if (node->isScalarInt()) return false; error(node->getLine(), "integer expression required", token); @@ -437,7 +435,7 @@ bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& id error(line, reservedErrMsg, "gl_"); return true; } - if (isWebGLBasedSpec(shaderSpec)) { + if (IsWebGLBasedSpec(shaderSpec)) { if (identifier.compare(0, 6, "webgl_") == 0) { error(line, reservedErrMsg, "webgl_"); return true; @@ -535,7 +533,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n return true; } - if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) { + if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) { error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); return true; } @@ -599,7 +597,7 @@ bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* t // bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TPublicType& pType) { - if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) { + if (pType.type != EbtBool || pType.isAggregate()) { error(line, "boolean expression expected", ""); return true; } @@ -628,11 +626,20 @@ bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType) { - if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && - pType.type == EbtStruct) { - error(line, "cannot be used with a structure", getQualifierString(pType.qualifier)); - - return true; + switch (pType.qualifier) + { + case EvqVaryingIn: + case EvqVaryingOut: + case EvqAttribute: + case EvqVertexIn: + case EvqFragmentOut: + if (pType.type == EbtStruct) + { + error(line, "cannot be used with a structure", getQualifierString(pType.qualifier)); + return true; + } + + default: break; } if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform")) @@ -641,6 +648,17 @@ bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPub return false; } +bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType) +{ + if (pType.layoutQualifier.location != -1) + { + error(line, "location must only be specified for a single input or output variable", "location"); + return true; + } + + return false; +} + bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type) { if ((qualifier == EvqOut || qualifier == EvqInOut) && @@ -657,7 +675,7 @@ bool TParseContext::containsSampler(TType& type) if (IsSampler(type.getBasicType())) return true; - if (type.getBasicType() == EbtStruct) { + if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) { const TFieldList& fields = type.getStruct()->fields(); for (unsigned int i = 0; i < fields.size(); ++i) { if (containsSampler(*fields[i]->type())) @@ -676,15 +694,49 @@ bool TParseContext::containsSampler(TType& type) bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size) { TIntermConstantUnion* constant = expr->getAsConstantUnion(); - if (constant == 0 || constant->getBasicType() != EbtInt) { + + if (constant == 0 || !constant->isScalarInt()) + { error(line, "array size must be a constant integer expression", ""); return true; } - size = constant->getIConst(0); + unsigned int unsignedSize = 0; + + if (constant->getBasicType() == EbtUInt) + { + unsignedSize = constant->getUConst(0); + size = static_cast<int>(unsignedSize); + } + else + { + size = constant->getIConst(0); + + if (size < 0) + { + error(line, "array size must be non-negative", ""); + size = 1; + return true; + } + + unsignedSize = static_cast<unsigned int>(size); + } - if (size <= 0) { - error(line, "array size must be a positive integer", ""); + if (size == 0) + { + error(line, "array size must be greater than zero", ""); + size = 1; + return true; + } + + // The size of arrays is restricted here to prevent issues further down the + // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to + // 4096 registers so this should be reasonable even for aggressively optimizable code. + const unsigned int sizeLimit = 65536; + + if (unsignedSize > sizeLimit) + { + error(line, "array size too large", ""); size = 1; return true; } @@ -699,7 +751,7 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* ex // bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type) { - if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) { + if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConst)) { error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str()); return true; } @@ -733,7 +785,7 @@ bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type // // Returns true if there was an error. // -bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable) +bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType &type, TVariable*& variable) { // // Don't check for reserved word use until after we know it's not in the symbol table, @@ -742,7 +794,7 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, bool builtIn = false; bool sameScope = false; - TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope); + TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope); if (symbol == 0 || !sameScope) { if (reservedErrorCheck(line, identifier)) return true; @@ -752,7 +804,7 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, if (type.arraySize) variable->getType().setArraySize(type.arraySize); - if (! symbolTable.insert(*variable)) { + if (! symbolTable.declare(*variable)) { delete variable; error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str()); return true; @@ -793,7 +845,7 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, // // Returns true if there was an error. // -bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array) +bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, const TString& identifier, TPublicType& type, bool array) { if (type.qualifier == EvqConst) { @@ -825,14 +877,14 @@ bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, TString& iden // // Returns true if there was an error. // -bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable) +bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& type, TVariable*& variable) { if (reservedErrorCheck(line, identifier)) recover(); variable = new TVariable(&identifier, TType(type)); - if (! symbolTable.insert(*variable)) { + if (! symbolTable.declare(*variable)) { error(line, "redefinition", variable->getName().c_str()); delete variable; variable = 0; @@ -885,6 +937,45 @@ bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& e return false; } +bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier) +{ + if (structQualifierErrorCheck(identifierLocation, publicType)) + return true; + + // check for layout qualifier issues + const TLayoutQualifier layoutQualifier = publicType.layoutQualifier; + + if (layoutQualifier.matrixPacking != EmpUnspecified) + { + error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking), "only valid for interface blocks"); + return true; + } + + if (layoutQualifier.blockStorage != EbsUnspecified) + { + error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage), "only valid for interface blocks"); + return true; + } + + if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier)) + { + return true; + } + + return false; +} + +bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier) +{ + if (layoutQualifier.location != -1) + { + error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs"); + return true; + } + + return false; +} + bool TParseContext::supportsExtension(const char* extension) { const TExtensionBehavior& extbehavior = extensionBehavior(); @@ -905,6 +996,22 @@ bool TParseContext::isExtensionEnabled(const char* extension) const return (iter->second == EBhEnable || iter->second == EBhRequire); } +void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior) +{ + pp::SourceLocation srcLoc; + srcLoc.file = loc.first_file; + srcLoc.line = loc.first_line; + directiveHandler.handleExtension(srcLoc, extName, behavior); +} + +void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value) +{ + pp::SourceLocation srcLoc; + srcLoc.file = loc.first_file; + srcLoc.line = loc.first_line; + directiveHandler.handlePragma(srcLoc, name, value); +} + ///////////////////////////////////////////////////////////////////////////////// // // Non-Errors. @@ -916,14 +1023,14 @@ bool TParseContext::isExtensionEnabled(const char* extension) const // // Return the function symbol if found, otherwise 0. // -const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, bool *builtIn) +const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int shaderVersion, bool *builtIn) { // First find by unmangled name to check whether the function name has been // hidden by a variable name or struct typename. // If a function is found, check for one with a matching argument list. - const TSymbol* symbol = symbolTable.find(call->getName(), builtIn); + const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn); if (symbol == 0 || symbol->isFunction()) { - symbol = symbolTable.find(call->getMangledName(), builtIn); + symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn); } if (symbol == 0) { @@ -943,7 +1050,7 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* // Initializers show up in several places in the grammar. Have one set of // code to handle them here. // -bool TParseContext::executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType, +bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) { TType type = TType(pType); @@ -959,7 +1066,7 @@ bool TParseContext::executeInitializer(const TSourceLoc& line, TString& identifi // add variable to symbol table // variable = new TVariable(&identifier, type); - if (! symbolTable.insert(*variable)) { + if (! symbolTable.declare(*variable)) { error(line, "redefinition", variable->getName().c_str()); return true; // don't delete variable, it's used by error recovery, and the pool @@ -997,7 +1104,7 @@ bool TParseContext::executeInitializer(const TSourceLoc& line, TString& identifi if (initializer->getAsConstantUnion()) { variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); } else if (initializer->getAsSymbolNode()) { - const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol()); + const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0); const TVariable* tVar = static_cast<const TVariable*>(symbol); ConstantUnion* constArray = tVar->getConstPointer(); @@ -1044,6 +1151,381 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) return allConstant; } +TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier) +{ + TPublicType returnType = typeSpecifier; + returnType.qualifier = qualifier; + returnType.layoutQualifier = layoutQualifier; + + if (typeSpecifier.array) + { + error(typeSpecifier.line, "not supported", "first-class array"); + recover(); + returnType.setArray(false); + } + + if (shaderVersion < 300) + { + if (qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + { + error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); + recover(); + } + + if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) && + (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + { + error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); + recover(); + } + } + else + { + switch (qualifier) + { + case EvqSmoothIn: + case EvqSmoothOut: + case EvqVertexOut: + case EvqFragmentIn: + case EvqCentroidOut: + case EvqCentroidIn: + if (typeSpecifier.type == EbtBool) + { + error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier)); + recover(); + } + if (typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt) + { + error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier)); + recover(); + } + break; + + case EvqVertexIn: + case EvqFragmentOut: + case EvqFlatIn: + case EvqFlatOut: + if (typeSpecifier.type == EbtBool) + { + error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier)); + recover(); + } + break; + + default: break; + } + } + + return returnType; +} + +TIntermAggregate* TParseContext::parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier) +{ + TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); + TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation); + + if (identifier != "") + { + if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier)) + recover(); + + // this error check can mutate the type + if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false)) + recover(); + + TVariable* variable = 0; + + if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable)) + recover(); + + if (variable && symbol) + { + symbol->setId(variable->getUniqueId()); + } + } + + return aggregate; +} + +TIntermAggregate* TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression) +{ + if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier)) + recover(); + + // this error check can mutate the type + if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true)) + recover(); + + if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) + { + recover(); + } + + TPublicType arrayType = publicType; + + int size; + if (arraySizeErrorCheck(identifierLocation, indexExpression, size)) + { + recover(); + } + else + { + arrayType.setArray(true, size); + } + + TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(arrayType), identifierLocation); + TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation); + TVariable* variable = 0; + + if (arrayErrorCheck(identifierLocation, identifier, arrayType, variable)) + recover(); + + if (variable && symbol) + { + symbol->setId(variable->getUniqueId()); + } + + return aggregate; +} + +TIntermAggregate* TParseContext::parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer) +{ + if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier)) + recover(); + + TIntermNode* intermNode; + if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode)) + { + // + // Build intermediate representation + // + return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : NULL; + } + else + { + recover(); + return NULL; + } +} + +TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier) +{ + if (publicType.type == EbtInvariant && !identifierSymbol) + { + error(identifierLocation, "undeclared identifier declared as invariant", identifier.c_str()); + recover(); + } + + TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); + TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation); + + if (structQualifierErrorCheck(identifierLocation, publicType)) + recover(); + + if (locationDeclaratorListCheck(identifierLocation, publicType)) + recover(); + + if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false)) + recover(); + + TVariable* variable = 0; + if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable)) + recover(); + if (symbol && variable) + symbol->setId(variable->getUniqueId()); + + return intermAggregate; +} + +TIntermAggregate* TParseContext::parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression) +{ + if (structQualifierErrorCheck(identifierLocation, publicType)) + recover(); + + if (locationDeclaratorListCheck(identifierLocation, publicType)) + recover(); + + if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true)) + recover(); + + if (arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType)) + { + recover(); + } + else if (indexExpression) + { + int size; + if (arraySizeErrorCheck(arrayLocation, indexExpression, size)) + recover(); + TPublicType arrayType(publicType); + arrayType.setArray(true, size); + TVariable* variable = NULL; + if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable)) + recover(); + TType type = TType(arrayType); + type.setArraySize(size); + + return intermediate.growAggregate(declaratorList, intermediate.addSymbol(variable ? variable->getUniqueId() : 0, identifier, type, identifierLocation), identifierLocation); + } + else + { + TPublicType arrayType(publicType); + arrayType.setArray(true); + TVariable* variable = NULL; + if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable)) + recover(); + } + + return NULL; +} + +TIntermAggregate* TParseContext::parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer) +{ + if (structQualifierErrorCheck(identifierLocation, publicType)) + recover(); + + if (locationDeclaratorListCheck(identifierLocation, publicType)) + recover(); + + TIntermNode* intermNode; + if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode)) + { + // + // build the intermediate representation + // + if (intermNode) + { + return intermediate.growAggregate(declaratorList, intermNode, initLocation); + } + else + { + return declaratorList; + } + } + else + { + recover(); + return NULL; + } +} + +void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) +{ + if (typeQualifier.qualifier != EvqUniform) + { + error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform"); + recover(); + return; + } + + const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier; + ASSERT(!layoutQualifier.isEmpty()); + + if (shaderVersion < 300) + { + error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout"); + recover(); + return; + } + + if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier)) + { + recover(); + return; + } + + if (layoutQualifier.matrixPacking != EmpUnspecified) + { + defaultMatrixPacking = layoutQualifier.matrixPacking; + } + + if (layoutQualifier.blockStorage != EbsUnspecified) + { + defaultBlockStorage = layoutQualifier.blockStorage; + } +} + +TFunction *TParseContext::addConstructorFunc(TPublicType publicType) +{ + TOperator op = EOpNull; + if (publicType.userDef) + { + op = EOpConstructStruct; + } + else + { + switch (publicType.type) + { + case EbtFloat: + if (publicType.isMatrix()) + { + // TODO: non-square matrices + switch(publicType.getCols()) + { + case 2: op = EOpConstructMat2; break; + case 3: op = EOpConstructMat3; break; + case 4: op = EOpConstructMat4; break; + } + } + else + { + switch(publicType.getNominalSize()) + { + case 1: op = EOpConstructFloat; break; + case 2: op = EOpConstructVec2; break; + case 3: op = EOpConstructVec3; break; + case 4: op = EOpConstructVec4; break; + } + } + break; + + case EbtInt: + switch(publicType.getNominalSize()) + { + case 1: op = EOpConstructInt; break; + case 2: op = EOpConstructIVec2; break; + case 3: op = EOpConstructIVec3; break; + case 4: op = EOpConstructIVec4; break; + } + break; + + case EbtUInt: + switch(publicType.getNominalSize()) + { + case 1: op = EOpConstructUInt; break; + case 2: op = EOpConstructUVec2; break; + case 3: op = EOpConstructUVec3; break; + case 4: op = EOpConstructUVec4; break; + } + break; + + case EbtBool: + switch(publicType.getNominalSize()) + { + case 1: op = EOpConstructBool; break; + case 2: op = EOpConstructBVec2; break; + case 3: op = EOpConstructBVec3; break; + case 4: op = EOpConstructBVec4; break; + } + break; + + default: break; + } + + if (op == EOpNull) + { + error(publicType.line, "cannot construct this type", getBasicString(publicType.type)); + recover(); + publicType.type = EbtFloat; + op = EOpConstructFloat; + } + } + + TString tempString; + TType type(publicType); + return new TFunction(&tempString, type, op); +} + // This function is used to test for the correctness of the parameters passed to various constructor functions // and also convert them to the right datatype if it is allowed and required. // @@ -1056,9 +1538,9 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type TIntermAggregate* aggrNode = node->getAsAggregate(); - TFieldList::const_iterator memberFields; + TFieldList::const_iterator memberTypes; if (op == EOpConstructStruct) - memberFields = type->getStruct()->fields().begin(); + memberTypes = type->getStruct()->fields().begin(); TType elementType = *type; if (type->isArray()) @@ -1080,7 +1562,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type if (type->isArray()) newNode = constructStruct(node, &elementType, 1, node->getLine(), false); else if (op == EOpConstructStruct) - newNode = constructStruct(node, (*memberFields)->type(), 1, node->getLine(), false); + newNode = constructStruct(node, (*memberTypes)->type(), 1, node->getLine(), false); else newNode = constructBuiltIn(type, op, node, node->getLine(), false); @@ -1111,7 +1593,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type if (type->isArray()) newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true); else if (op == EOpConstructStruct) - newNode = constructStruct(*p, memberFields[paramCount]->type(), paramCount+1, node->getLine(), true); + newNode = constructStruct(*p, (memberTypes[paramCount])->type(), paramCount+1, node->getLine(), true); else newNode = constructBuiltIn(type, op, *p, node->getLine(), true); @@ -1136,10 +1618,10 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co bool returnVal = false; ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()]; if (aggrNode->getSequence().size() == 1) { - returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type, true); + returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true); } else { - returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type); + returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type); } if (returnVal) return 0; @@ -1183,6 +1665,13 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T basicOp = EOpConstructInt; break; + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructUInt: + basicOp = EOpConstructUInt; + break; + case EOpConstructBVec2: case EOpConstructBVec3: case EOpConstructBVec4: @@ -1196,7 +1685,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T return 0; } - newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable); + newNode = intermediate.addUnaryMath(basicOp, node, node->getLine()); if (newNode == 0) { error(line, "can't convert", "constructor"); return 0; @@ -1295,7 +1784,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, c TIntermTyped* typedNode; TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); - if (index >= node->getType().getNominalSize()) { + if (index >= node->getType().getCols()) { std::stringstream extraInfoStream; extraInfoStream << "matrix field selection out of range '" << index << "'"; std::string extraInfo = extraInfoStream.str(); @@ -1306,7 +1795,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, c if (tempConstantNode) { ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); - int size = tempConstantNode->getType().getNominalSize(); + int size = tempConstantNode->getType().getCols(); typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); } else { error(line, "Cannot offset into the matrix", "Error"); @@ -1342,9 +1831,9 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co } if (tempConstantNode) { - size_t arrayElementSize = arrayElementType.getObjectSize(); - ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); - typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); + size_t arrayElementSize = arrayElementType.getObjectSize(); + ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); + typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); } else { error(line, "Cannot offset into the array", "Error"); recover(); @@ -1361,11 +1850,11 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr // function and returns the parse-tree with the values of the embedded/nested struct. // -TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, const TSourceLoc& line) +TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line) { const TFieldList& fields = node->getType().getStruct()->fields(); - size_t instanceSize = 0; + for (size_t index = 0; index < fields.size(); ++index) { if (fields[index]->name() == identifier) { break; @@ -1374,8 +1863,8 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n } } - TIntermTyped* typedNode = 0; - TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); + TIntermTyped *typedNode; + TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); if (tempConstantNode) { ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer(); @@ -1390,6 +1879,146 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n return typedNode; } +// +// Interface/uniform blocks +// +TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, + const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine) +{ + if (reservedErrorCheck(nameLine, blockName)) + recover(); + + if (typeQualifier.qualifier != EvqUniform) + { + error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform"); + recover(); + } + + TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier; + if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier)) + { + recover(); + } + + if (blockLayoutQualifier.matrixPacking == EmpUnspecified) + { + blockLayoutQualifier.matrixPacking = defaultMatrixPacking; + } + + if (blockLayoutQualifier.blockStorage == EbsUnspecified) + { + blockLayoutQualifier.blockStorage = defaultBlockStorage; + } + + TSymbol* blockNameSymbol = new TInterfaceBlockName(&blockName); + if (!symbolTable.declare(*blockNameSymbol)) { + error(nameLine, "redefinition", blockName.c_str(), "interface block name"); + recover(); + } + + // check for sampler types and apply layout qualifiers + for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) { + TField* field = (*fieldList)[memberIndex]; + TType* fieldType = field->type(); + if (IsSampler(fieldType->getBasicType())) { + error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks"); + recover(); + } + + const TQualifier qualifier = fieldType->getQualifier(); + switch (qualifier) + { + case EvqGlobal: + case EvqUniform: + break; + default: + error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier)); + recover(); + break; + } + + // check layout qualifiers + TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier(); + if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier)) + { + recover(); + } + + if (fieldLayoutQualifier.blockStorage != EbsUnspecified) + { + error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); + recover(); + } + + if (fieldLayoutQualifier.matrixPacking == EmpUnspecified) + { + fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking; + } + else if (!fieldType->isMatrix()) + { + error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types"); + recover(); + } + + fieldType->setLayoutQualifier(fieldLayoutQualifier); + } + + // add array index + int arraySize = 0; + if (arrayIndex != NULL) + { + if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize)) + recover(); + } + + TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier); + TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize); + + TString symbolName = ""; + int symbolId = 0; + + if (!instanceName) + { + // define symbols for the members of the interface block + for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) + { + TField* field = (*fieldList)[memberIndex]; + TType* fieldType = field->type(); + + // set parent pointer of the field variable + fieldType->setInterfaceBlock(interfaceBlock); + + TVariable* fieldVariable = new TVariable(&field->name(), *fieldType); + fieldVariable->setQualifier(typeQualifier.qualifier); + + if (!symbolTable.declare(*fieldVariable)) { + error(field->line(), "redefinition", field->name().c_str(), "interface block member name"); + recover(); + } + } + } + else + { + // add a symbol for this interface block + TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); + instanceTypeDef->setQualifier(typeQualifier.qualifier); + + if (!symbolTable.declare(*instanceTypeDef)) { + error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name"); + recover(); + } + + symbolId = instanceTypeDef->getUniqueId(); + symbolName = instanceTypeDef->getName(); + } + + TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine); + aggregate->setOp(EOpDeclaration); + + exitStructDeclaration(); + return aggregate; +} + bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier) { ++structNestingLevel; @@ -1418,7 +2047,7 @@ const int kWebGLMaxStructNesting = 4; bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field) { - if (!isWebGLBasedSpec(shaderSpec)) { + if (!IsWebGLBasedSpec(shaderSpec)) { return false; } @@ -1531,6 +2160,17 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co } else { + if (baseExpression->isInterfaceBlock()) + { + error(location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions"); + recover(); + } + else if (baseExpression->getQualifier() == EvqFragmentOut) + { + error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions"); + recover(); + } + indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); } @@ -1548,9 +2188,14 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co TType copyOfType(baseType.getStruct()); indexedExpression->setType(copyOfType); } + else if (baseType.isInterfaceBlock()) + { + TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(), baseType.getLayoutQualifier(), 0); + indexedExpression->setType(copyOfType); + } else { - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->isMatrix())); + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->getSecondarySize())); } if (baseExpression->getType().getQualifier() == EvqConst) @@ -1561,7 +2206,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co else if (baseExpression->isMatrix()) { TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getNominalSize())); + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getRows())); } else if (baseExpression->isVector()) { @@ -1576,6 +2221,408 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co return indexedExpression; } +TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation) +{ + TIntermTyped *indexedExpression = NULL; + + if (baseExpression->isArray()) + { + error(fieldLocation, "cannot apply dot operator to an array", "."); + recover(); + } + + if (baseExpression->isVector()) + { + TVectorFields fields; + if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation)) + { + fields.num = 1; + fields.offsets[0] = 0; + recover(); + } + + if (baseExpression->getType().getQualifier() == EvqConst) + { + // constant folding for vector fields + indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation); + if (indexedExpression == 0) + { + recover(); + indexedExpression = baseExpression; + } + else + { + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, (int) (fieldString).size())); + } + } + else + { + TString vectorString = fieldString; + TIntermTyped* index = intermediate.addSwizzle(fields, fieldLocation); + indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation); + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, (int) vectorString.size())); + } + } + else if (baseExpression->isMatrix()) + { + TMatrixFields fields; + if (!parseMatrixFields(fieldString, baseExpression->getCols(), baseExpression->getRows(), fields, fieldLocation)) + { + fields.wholeRow = false; + fields.wholeCol = false; + fields.row = 0; + fields.col = 0; + recover(); + } + + if (fields.wholeRow || fields.wholeCol) + { + error(dotLocation, " non-scalar fields not implemented yet", "."); + recover(); + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setIConst(0); + TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation); + indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation); + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),EvqTemporary, baseExpression->getCols(), baseExpression->getRows())); + } + else + { + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setIConst(fields.col * baseExpression->getRows() + fields.row); + TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation); + indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation); + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision())); + } + } + else if (baseExpression->getBasicType() == EbtStruct) + { + bool fieldFound = false; + const TFieldList& fields = baseExpression->getType().getStruct()->fields(); + if (fields.empty()) + { + error(dotLocation, "structure has no fields", "Internal Error"); + recover(); + indexedExpression = baseExpression; + } + else + { + unsigned int i; + for (i = 0; i < fields.size(); ++i) + { + if (fields[i]->name() == fieldString) + { + fieldFound = true; + break; + } + } + if (fieldFound) + { + if (baseExpression->getType().getQualifier() == EvqConst) + { + indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation); + if (indexedExpression == 0) + { + recover(); + indexedExpression = baseExpression; + } + else + { + indexedExpression->setType(*fields[i]->type()); + // change the qualifier of the return type, not of the structure field + // as the structure definition is shared between various structures. + indexedExpression->getTypePointer()->setQualifier(EvqConst); + } + } + else + { + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setIConst(i); + TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); + indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation); + indexedExpression->setType(*fields[i]->type()); + } + } + else + { + error(dotLocation, " no such field in structure", fieldString.c_str()); + recover(); + indexedExpression = baseExpression; + } + } + } + else if (baseExpression->isInterfaceBlock()) + { + bool fieldFound = false; + const TFieldList& fields = baseExpression->getType().getInterfaceBlock()->fields(); + if (fields.empty()) + { + error(dotLocation, "interface block has no fields", "Internal Error"); + recover(); + indexedExpression = baseExpression; + } + else + { + unsigned int i; + for (i = 0; i < fields.size(); ++i) + { + if (fields[i]->name() == fieldString) + { + fieldFound = true; + break; + } + } + if (fieldFound) + { + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setIConst(i); + TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); + indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, dotLocation); + indexedExpression->setType(*fields[i]->type()); + } + else + { + error(dotLocation, " no such field in interface block", fieldString.c_str()); + recover(); + indexedExpression = baseExpression; + } + } + } + else + { + if (shaderVersion < 300) + { + error(dotLocation, " field selection requires structure, vector, or matrix on left hand side", fieldString.c_str()); + } + else + { + error(dotLocation, " field selection requires structure, vector, matrix, or interface block on left hand side", fieldString.c_str()); + } + recover(); + indexedExpression = baseExpression; + } + + return indexedExpression; +} + +TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine) +{ + TLayoutQualifier qualifier; + + qualifier.location = -1; + qualifier.matrixPacking = EmpUnspecified; + qualifier.blockStorage = EbsUnspecified; + + if (qualifierType == "shared") + { + qualifier.blockStorage = EbsShared; + } + else if (qualifierType == "packed") + { + qualifier.blockStorage = EbsPacked; + } + else if (qualifierType == "std140") + { + qualifier.blockStorage = EbsStd140; + } + else if (qualifierType == "row_major") + { + qualifier.matrixPacking = EmpRowMajor; + } + else if (qualifierType == "column_major") + { + qualifier.matrixPacking = EmpColumnMajor; + } + else if (qualifierType == "location") + { + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument"); + recover(); + } + else + { + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str()); + recover(); + } + + return qualifier; +} + +TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine) +{ + TLayoutQualifier qualifier; + + qualifier.location = -1; + qualifier.matrixPacking = EmpUnspecified; + qualifier.blockStorage = EbsUnspecified; + + if (qualifierType != "location") + { + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments"); + recover(); + } + else + { + // must check that location is non-negative + if (intValue < 0) + { + error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative"); + recover(); + } + else + { + qualifier.location = intValue; + } + } + + return qualifier; +} + +TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier) +{ + TLayoutQualifier joinedQualifier = leftQualifier; + + if (rightQualifier.location != -1) + { + joinedQualifier.location = rightQualifier.location; + } + if (rightQualifier.matrixPacking != EmpUnspecified) + { + joinedQualifier.matrixPacking = rightQualifier.matrixPacking; + } + if (rightQualifier.blockStorage != EbsUnspecified) + { + joinedQualifier.blockStorage = rightQualifier.blockStorage; + } + + return joinedQualifier; +} + +TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, + const TSourceLoc &storageLoc, TQualifier storageQualifier) +{ + TQualifier mergedQualifier = EvqSmoothIn; + + if (storageQualifier == EvqFragmentIn) { + if (interpolationQualifier == EvqSmooth) + mergedQualifier = EvqSmoothIn; + else if (interpolationQualifier == EvqFlat) + mergedQualifier = EvqFlatIn; + else UNREACHABLE(); + } + else if (storageQualifier == EvqCentroidIn) { + if (interpolationQualifier == EvqSmooth) + mergedQualifier = EvqCentroidIn; + else if (interpolationQualifier == EvqFlat) + mergedQualifier = EvqFlatIn; + else UNREACHABLE(); + } + else if (storageQualifier == EvqVertexOut) { + if (interpolationQualifier == EvqSmooth) + mergedQualifier = EvqSmoothOut; + else if (interpolationQualifier == EvqFlat) + mergedQualifier = EvqFlatOut; + else UNREACHABLE(); + } + else if (storageQualifier == EvqCentroidOut) { + if (interpolationQualifier == EvqSmooth) + mergedQualifier = EvqCentroidOut; + else if (interpolationQualifier == EvqFlat) + mergedQualifier = EvqFlatOut; + else UNREACHABLE(); + } + else { + error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString(interpolationQualifier)); + recover(); + + mergedQualifier = storageQualifier; + } + + TPublicType type; + type.setBasic(EbtVoid, mergedQualifier, storageLoc); + return type; +} + +TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList) +{ + if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier)) { + recover(); + } + + for (unsigned int i = 0; i < fieldList->size(); ++i) { + // + // Careful not to replace already known aspects of type, like array-ness + // + TType* type = (*fieldList)[i]->type(); + type->setBasicType(typeSpecifier.type); + type->setPrimarySize(typeSpecifier.primarySize); + type->setSecondarySize(typeSpecifier.secondarySize); + type->setPrecision(typeSpecifier.precision); + type->setQualifier(typeSpecifier.qualifier); + type->setLayoutQualifier(typeSpecifier.layoutQualifier); + + // don't allow arrays of arrays + if (type->isArray()) { + if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier)) + recover(); + } + if (typeSpecifier.array) + type->setArraySize(typeSpecifier.arraySize); + if (typeSpecifier.userDef) { + type->setStruct(typeSpecifier.userDef->getStruct()); + } + + if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) { + recover(); + } + } + + return fieldList; +} + +TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList) +{ + TStructure* structure = new TStructure(structName, fieldList); + TType* structureType = new TType(structure); + + structure->setUniqueId(TSymbolTable::nextUniqueId()); + + if (!structName->empty()) + { + if (reservedErrorCheck(nameLine, *structName)) + { + recover(); + } + TVariable* userTypeDef = new TVariable(structName, *structureType, true); + if (!symbolTable.declare(*userTypeDef)) { + error(nameLine, "redefinition", structName->c_str(), "struct"); + recover(); + } + } + + // ensure we do not specify any storage qualifiers on the struct members + for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++) + { + const TField &field = *(*fieldList)[typeListIndex]; + const TQualifier qualifier = field.type()->getQualifier(); + switch (qualifier) + { + case EvqGlobal: + case EvqTemporary: + break; + default: + error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier)); + recover(); + break; + } + } + + TPublicType publicType; + publicType.setBasic(EbtStruct, EvqTemporary, structLine); + publicType.userDef = structureType; + exitStructDeclaration(); + + return publicType; +} + // // Parse an array of strings using yyparse. // diff --git a/chromium/third_party/angle/src/compiler/ParseContext.h b/chromium/third_party/angle/src/compiler/translator/ParseContext.h index c2b3c3f7ec8..3cd4b915e3c 100644 --- a/chromium/third_party/angle/src/compiler/ParseContext.h +++ b/chromium/third_party/angle/src/compiler/translator/ParseContext.h @@ -6,12 +6,12 @@ #ifndef _PARSER_HELPER_INCLUDED_ #define _PARSER_HELPER_INCLUDED_ -#include "compiler/Diagnostics.h" -#include "compiler/DirectiveHandler.h" -#include "compiler/localintermediate.h" +#include "compiler/translator/Diagnostics.h" +#include "compiler/translator/DirectiveHandler.h" +#include "compiler/translator/localintermediate.h" +#include "compiler/translator/ShHandle.h" +#include "compiler/translator/SymbolTable.h" #include "compiler/preprocessor/Preprocessor.h" -#include "compiler/ShHandle.h" -#include "compiler/SymbolTable.h" struct TMatrixFields { bool wholeRow; @@ -38,14 +38,18 @@ struct TParseContext { currentFunctionType(NULL), functionReturnsValue(false), checksPrecisionErrors(checksPrecErrors), + defaultMatrixPacking(EmpColumnMajor), + defaultBlockStorage(EbsShared), diagnostics(is), - directiveHandler(ext, diagnostics), + shaderVersion(100), + directiveHandler(ext, diagnostics, shaderVersion), preprocessor(&diagnostics, &directiveHandler), scanner(NULL) { } TIntermediate& intermediate; // to hold and build a parse tree TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed ShShaderType shaderType; // vertex or fragment language (future: pack or unpack) ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + int shaderVersion; int compileOptions; const char* sourcePath; // Path of source file or NULL. TIntermNode* treeRoot; // root of parse tree being created @@ -55,12 +59,15 @@ struct TParseContext { bool functionReturnsValue; // true if a non-void function has a return bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language. + TLayoutMatrixPacking defaultMatrixPacking; + TLayoutBlockStorage defaultBlockStorage; TString HashErrMsg; TDiagnostics diagnostics; TDirectiveHandler directiveHandler; pp::Preprocessor preprocessor; void* scanner; + int getShaderVersion() const { return shaderVersion; } int numErrors() const { return diagnostics.numErrors(); } TInfoSink& infoSink() { return diagnostics.infoSink(); } void error(const TSourceLoc& loc, const char *reason, const char* token, @@ -71,7 +78,7 @@ struct TParseContext { void recover(); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line); - bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, const TSourceLoc& line); + bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc& line); bool reservedErrorCheck(const TSourceLoc& line, const TString& identifier); void assignError(const TSourceLoc& line, const char* op, TString left, TString right); @@ -86,29 +93,44 @@ struct TParseContext { bool arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size); bool arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type); bool arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type); - bool arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable); + bool arrayErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType &type, TVariable*& variable); bool voidErrorCheck(const TSourceLoc&, const TString&, const TPublicType&); bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*); bool boolErrorCheck(const TSourceLoc&, const TPublicType&); bool samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason); bool structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType); + bool locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType); bool parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type); - bool nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array); - bool nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable); + bool nonInitConstErrorCheck(const TSourceLoc& line, const TString& identifier, TPublicType& type, bool array); + bool nonInitErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& type, TVariable*& variable); bool paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type); bool extensionErrorCheck(const TSourceLoc& line, const TString&); + bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier); + bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier); const TPragma& pragma() const { return directiveHandler.pragma(); } const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); } bool supportsExtension(const char* extension); bool isExtensionEnabled(const char* extension) const; + void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior); + void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value); bool containsSampler(TType& type); bool areAllChildConst(TIntermAggregate* aggrNode); - const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0); - bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType, + const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int shaderVersion, bool *builtIn = 0); + bool executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); + TPublicType addFullySpecifiedType(TQualifier qualifier, const TPublicType& typeSpecifier); + TPublicType addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier); + TIntermAggregate* parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier); + TIntermAggregate* parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression); + TIntermAggregate* parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer); + TIntermAggregate* parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier); + TIntermAggregate* parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression); + TIntermAggregate* parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer); + void parseGlobalLayoutQualifier(const TPublicType &typeQualifier); + TFunction *addConstructorFunc(TPublicType publicType); TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&); TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type); TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&, bool subset); @@ -116,8 +138,21 @@ struct TParseContext { TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&); TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&); TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line); - TIntermTyped* addConstStruct(TString& , TIntermTyped*, const TSourceLoc&); + TIntermTyped* addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line); TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression); + TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation); + + TFieldList *addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList); + TPublicType addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList); + + TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, + const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine); + + TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine); + TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine); + TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier); + TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, + const TSourceLoc &storageLoc, TQualifier storageQualifier); // Performs an error check for embedded struct declarations. // Returns true if an error was raised due to the declaration of diff --git a/chromium/third_party/angle/src/compiler/PoolAlloc.cpp b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.cpp index eb993567b35..abe70262f2d 100644 --- a/chromium/third_party/angle/src/compiler/PoolAlloc.cpp +++ b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/PoolAlloc.h" +#include "compiler/translator/PoolAlloc.h" #ifndef _MSC_VER #include <stdint.h> @@ -12,8 +12,8 @@ #include <stdio.h> #include "common/angleutils.h" -#include "compiler/InitializeGlobals.h" -#include "compiler/osinclude.h" +#include "compiler/translator/InitializeGlobals.h" +#include "compiler/translator/osinclude.h" OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX; diff --git a/chromium/third_party/angle/src/compiler/PoolAlloc.h b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.h index edd249c4d3a..edd249c4d3a 100644 --- a/chromium/third_party/angle/src/compiler/PoolAlloc.h +++ b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.h diff --git a/chromium/third_party/angle/src/compiler/Pragma.h b/chromium/third_party/angle/src/compiler/translator/Pragma.h index 2f744123b82..2f744123b82 100644 --- a/chromium/third_party/angle/src/compiler/Pragma.h +++ b/chromium/third_party/angle/src/compiler/translator/Pragma.h diff --git a/chromium/third_party/angle/src/compiler/QualifierAlive.cpp b/chromium/third_party/angle/src/compiler/translator/QualifierAlive.cpp index 92a6874eb7b..1ba087e1765 100644 --- a/chromium/third_party/angle/src/compiler/QualifierAlive.cpp +++ b/chromium/third_party/angle/src/compiler/translator/QualifierAlive.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" class TAliveTraverser : public TIntermTraverser { public: diff --git a/chromium/third_party/angle/src/compiler/QualifierAlive.h b/chromium/third_party/angle/src/compiler/translator/QualifierAlive.h index 872a06f7219..872a06f7219 100644 --- a/chromium/third_party/angle/src/compiler/QualifierAlive.h +++ b/chromium/third_party/angle/src/compiler/translator/QualifierAlive.h diff --git a/chromium/third_party/angle/src/compiler/translator/RemoveTree.cpp b/chromium/third_party/angle/src/compiler/translator/RemoveTree.cpp new file mode 100644 index 00000000000..e381c326900 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RemoveTree.cpp @@ -0,0 +1,29 @@ +// +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/intermediate.h" +#include "compiler/translator/RemoveTree.h" + +// +// Code to delete the intermediate tree. +// +void RemoveAllTreeNodes(TIntermNode* root) +{ + std::queue<TIntermNode*> nodeQueue; + + nodeQueue.push(root); + + while (!nodeQueue.empty()) + { + TIntermNode *node = nodeQueue.front(); + nodeQueue.pop(); + + node->enqueueChildren(&nodeQueue); + + delete node; + } +} + diff --git a/chromium/third_party/angle/src/compiler/RemoveTree.h b/chromium/third_party/angle/src/compiler/translator/RemoveTree.h index 97a821679c2..97a821679c2 100644 --- a/chromium/third_party/angle/src/compiler/RemoveTree.h +++ b/chromium/third_party/angle/src/compiler/translator/RemoveTree.h diff --git a/chromium/third_party/angle/src/compiler/RenameFunction.h b/chromium/third_party/angle/src/compiler/translator/RenameFunction.h index 3908bfddb82..1f7fb16c459 100644 --- a/chromium/third_party/angle/src/compiler/RenameFunction.h +++ b/chromium/third_party/angle/src/compiler/translator/RenameFunction.h @@ -7,7 +7,7 @@ #ifndef COMPILER_RENAME_FUNCTION #define COMPILER_RENAME_FUNCTION -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" // // Renames a function, including its declaration and any calls to it. diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp b/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp new file mode 100644 index 00000000000..46e510c31b9 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp @@ -0,0 +1,132 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RewriteElseBlocks.cpp: Implementation for tree transform to change +// all if-else blocks to if-if blocks. +// + +#include "compiler/translator/RewriteElseBlocks.h" +#include "compiler/translator/NodeSearch.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type) +{ + TType variableType(type, EbpHigh, EvqInternal); + return new TIntermSymbol(-1, name, variableType); +} + +TIntermBinary *MakeNewBinary(TOperator op, TIntermTyped *left, TIntermTyped *right, const TType &resultType) +{ + TIntermBinary *binary = new TIntermBinary(op); + binary->setLeft(left); + binary->setRight(right); + binary->setType(resultType); + return binary; +} + +TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand) +{ + TIntermUnary *unary = new TIntermUnary(op, operand->getType()); + unary->setOperand(operand); + return unary; +} + +ElseBlockRewriter::ElseBlockRewriter() + : TIntermTraverser(true, false, true, false), + mTemporaryIndex(0), + mFunctionType(NULL) +{} + +bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) +{ + switch (node->getOp()) + { + case EOpSequence: + if (visit == PostVisit) + { + for (size_t statementIndex = 0; statementIndex != node->getSequence().size(); statementIndex++) + { + TIntermNode *statement = node->getSequence()[statementIndex]; + TIntermSelection *selection = statement->getAsSelectionNode(); + if (selection && selection->getFalseBlock() != NULL) + { + // Check for if / else if + TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode(); + if (elseIfBranch) + { + selection->replaceChildNode(elseIfBranch, rewriteSelection(elseIfBranch)); + delete elseIfBranch; + } + + node->getSequence()[statementIndex] = rewriteSelection(selection); + delete selection; + } + } + } + break; + + case EOpFunction: + // Store the current function context (see comment below) + mFunctionType = ((visit == PreVisit) ? &node->getType() : NULL); + break; + + default: break; + } + + return true; +} + +TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) +{ + ASSERT(selection->getFalseBlock() != NULL); + + TString temporaryName = "cond_" + str(mTemporaryIndex++); + TIntermTyped *typedCondition = selection->getCondition()->getAsTyped(); + TType resultType(EbtBool, EbpUndefined); + TIntermSymbol *conditionSymbolA = MakeNewTemporary(temporaryName, EbtBool); + TIntermSymbol *conditionSymbolB = MakeNewTemporary(temporaryName, EbtBool); + TIntermSymbol *conditionSymbolC = MakeNewTemporary(temporaryName, EbtBool); + TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolA, + typedCondition, resultType); + TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolB); + TIntermNode *negatedElse = NULL; + + // crbug.com/346463 + // D3D generates error messages claiming a function has no return value, when rewriting + // an if-else clause that returns something non-void in a function. By appending dummy + // returns (that are unreachable) we can silence this compile error. + if (mFunctionType && mFunctionType->getBasicType() != EbtVoid) + { + TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() : + mFunctionType->getBasicString(); + TString rawText = "return (" + typeString + ")0"; + negatedElse = new TIntermRaw(*mFunctionType, rawText); + } + + TIntermSelection *falseBlock = new TIntermSelection(negatedCondition, + selection->getFalseBlock(), negatedElse); + TIntermSelection *newIfElse = new TIntermSelection(conditionSymbolC, + selection->getTrueBlock(), falseBlock); + + TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration); + declaration->getSequence().push_back(storeCondition); + + TIntermAggregate *block = new TIntermAggregate(EOpSequence); + block->getSequence().push_back(declaration); + block->getSequence().push_back(newIfElse); + + return block; +} + +void RewriteElseBlocks(TIntermNode *node) +{ + ElseBlockRewriter rewriter; + node->traverse(&rewriter); +} + +} diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.h b/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.h new file mode 100644 index 00000000000..172928f7254 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.h @@ -0,0 +1,37 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RewriteElseBlocks.h: Prototype for tree transform to change +// all if-else blocks to if-if blocks. +// + +#ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_ +#define COMPILER_REWRITE_ELSE_BLOCKS_H_ + +#include "compiler/translator/intermediate.h" + +namespace sh +{ + +class ElseBlockRewriter : public TIntermTraverser +{ + public: + ElseBlockRewriter(); + + protected: + bool visitAggregate(Visit visit, TIntermAggregate *aggregate); + + private: + int mTemporaryIndex; + const TType *mFunctionType; + + TIntermNode *rewriteSelection(TIntermSelection *selection); +}; + +void RewriteElseBlocks(TIntermNode *node); + +} + +#endif // COMPILER_REWRITE_ELSE_BLOCKS_H_ diff --git a/chromium/third_party/angle/src/compiler/SearchSymbol.cpp b/chromium/third_party/angle/src/compiler/translator/SearchSymbol.cpp index 9368f1a4faf..f78c84e370d 100644 --- a/chromium/third_party/angle/src/compiler/SearchSymbol.cpp +++ b/chromium/third_party/angle/src/compiler/translator/SearchSymbol.cpp @@ -6,10 +6,10 @@ // SearchSymbol is an AST traverser to detect the use of a given symbol name // -#include "compiler/SearchSymbol.h" +#include "compiler/translator/SearchSymbol.h" -#include "compiler/InfoSink.h" -#include "compiler/OutputHLSL.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/OutputHLSL.h" namespace sh { diff --git a/chromium/third_party/angle/src/compiler/SearchSymbol.h b/chromium/third_party/angle/src/compiler/translator/SearchSymbol.h index 224bc77c6f2..8ddd3cb1ac3 100644 --- a/chromium/third_party/angle/src/compiler/SearchSymbol.h +++ b/chromium/third_party/angle/src/compiler/translator/SearchSymbol.h @@ -9,8 +9,8 @@ #ifndef COMPILER_SEARCHSYMBOL_H_ #define COMPILER_SEARCHSYMBOL_H_ -#include "compiler/intermediate.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/intermediate.h" +#include "compiler/translator/ParseContext.h" namespace sh { diff --git a/chromium/third_party/angle/src/compiler/ShHandle.h b/chromium/third_party/angle/src/compiler/translator/ShHandle.h index 873580a99c6..bb6a60c519f 100644 --- a/chromium/third_party/angle/src/compiler/ShHandle.h +++ b/chromium/third_party/angle/src/compiler/translator/ShHandle.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -14,17 +14,14 @@ // This should not be included by driver code. // -#include "GLSLANG/ShaderLang.h" - -#include "compiler/BuiltInFunctionEmulator.h" -#include "compiler/ExtensionBehavior.h" -#include "compiler/HashNames.h" -#include "compiler/InfoSink.h" -#include "compiler/SymbolTable.h" -#include "compiler/VariableInfo.h" +#include "compiler/translator/BuiltInFunctionEmulator.h" +#include "compiler/translator/ExtensionBehavior.h" +#include "compiler/translator/HashNames.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/VariableInfo.h" #include "third_party/compiler/ArrayBoundsClamper.h" -class LongNameMap; class TCompiler; class TDependencyGraph; class TranslatorHLSL; @@ -33,7 +30,7 @@ class TranslatorHLSL; // Helper function to identify specs that are based on the WebGL spec, // like the CSS Shaders spec. // -bool isWebGLBasedSpec(ShShaderSpec spec); +bool IsWebGLBasedSpec(ShShaderSpec spec); // // The base class used to back handles returned to the driver. @@ -57,7 +54,7 @@ protected: // class TCompiler : public TShHandleBase { public: - TCompiler(ShShaderType type, ShShaderSpec spec); + TCompiler(ShShaderType type, ShShaderSpec spec, ShShaderOutput output); virtual ~TCompiler(); virtual TCompiler* getAsCompiler() { return this; } @@ -67,25 +64,31 @@ public: int compileOptions); // Get results of the last compilation. + int getShaderVersion() const { return shaderVersion; } TInfoSink& getInfoSink() { return infoSink; } const TVariableInfoList& getAttribs() const { return attribs; } const TVariableInfoList& getUniforms() const { return uniforms; } const TVariableInfoList& getVaryings() const { return varyings; } - int getMappedNameMaxLength() const; ShHashFunction64 getHashFunction() const { return hashFunction; } NameMap& getNameMap() { return nameMap; } TSymbolTable& getSymbolTable() { return symbolTable; } + ShShaderSpec getShaderSpec() const { return shaderSpec; } + ShShaderOutput getOutputType() const { return outputType; } + std::string getBuiltInResourcesString() const { return builtInResourcesString; } protected: ShShaderType getShaderType() const { return shaderType; } - ShShaderSpec getShaderSpec() const { return shaderSpec; } // Initialize symbol-table with built-in symbols. bool InitBuiltInSymbolTable(const ShBuiltInResources& resources); + // Compute the string representation of the built-in resources + void setResourceString(); // Clears the results from the previous compilation. void clearResults(); // Return true if function recursion is detected or call depth exceeded. bool detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth); + // Returns true if a program has no conflicting or missing fragment outputs + bool validateOutputs(TIntermNode* root); // Rewrites a shader's intermediate tree according to the CSS Shaders spec. void rewriteCSSShader(TIntermNode* root); // Returns true if the given shader does not exceed the minimum @@ -93,13 +96,21 @@ protected: bool validateLimitations(TIntermNode* root); // Collect info for all attribs, uniforms, varyings. void collectVariables(TIntermNode* root); - // Map long variable names into shorter ones. - void mapLongVariableNames(TIntermNode* root); // Translate to object code. virtual void translate(TIntermNode* root) = 0; // Returns true if, after applying the packing rules in the GLSL 1.017 spec // Appendix A, section 7, the shader does not use too many uniforms. bool enforcePackingRestrictions(); + // Insert statements to initialize varyings without static use in the beginning + // of main(). It is to work around a Mac driver where such varyings in a vertex + // shader may be optimized out incorrectly at compile time, causing a link failure. + // This function should only be applied to vertex shaders. + void initializeVaryingsWithoutStaticUse(TIntermNode* root); + // Insert gl_Position = vec4(0,0,0,0) to the beginning of main(). + // It is to work around a Linux driver bug where missing this causes compile failure + // while spec says it is allowed. + // This function should only be applied to vertex shaders. + void initializeGLPosition(TIntermNode* root); // Returns true if the shader passes the restrictions that aim to prevent timing attacks. bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph); // Returns true if the shader does not use samplers. @@ -107,7 +118,7 @@ protected: // Returns true if the shader does not use sampler dependent values to affect control // flow or in operations whose time can depend on the input values. bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph); - // Return true if the maximum expression complexity below the limit. + // Return true if the maximum expression complexity is below the limit. bool limitExpressionComplexity(TIntermNode* root); // Get built-in extensions with default behavior. const TExtensionBehavior& getExtensionBehavior() const; @@ -121,12 +132,14 @@ protected: private: ShShaderType shaderType; ShShaderSpec shaderSpec; + ShShaderOutput outputType; int maxUniformVectors; int maxExpressionComplexity; int maxCallStackDepth; ShBuiltInResources compileResources; + std::string builtInResourcesString; // Built-in symbol table for the given language, spec, and resources. // It is preserved from compile-to-compile. @@ -140,14 +153,12 @@ private: BuiltInFunctionEmulator builtInFunctionEmulator; // Results of compilation. + int shaderVersion; TInfoSink infoSink; // Output sink. TVariableInfoList attribs; // Active attributes in the compiled shader. TVariableInfoList uniforms; // Active uniforms in the compiled shader. TVariableInfoList varyings; // Varyings in the compiled shader. - // Cached copy of the ref-counted singleton. - LongNameMap* longNameMap; - // name hashing. ShHashFunction64 hashFunction; NameMap nameMap; diff --git a/chromium/third_party/angle/src/compiler/ShaderLang.cpp b/chromium/third_party/angle/src/compiler/translator/ShaderLang.cpp index 42cd5cc5c15..bf0587a34ce 100644 --- a/chromium/third_party/angle/src/compiler/ShaderLang.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ShaderLang.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,11 +11,13 @@ #include "GLSLANG/ShaderLang.h" -#include "compiler/InitializeDll.h" -#include "compiler/preprocessor/length_limits.h" -#include "compiler/ShHandle.h" -#include "compiler/TranslatorHLSL.h" -#include "compiler/VariablePacker.h" +#include "compiler/translator/InitializeDll.h" +#include "compiler/translator/length_limits.h" +#include "compiler/translator/ShHandle.h" +#include "compiler/translator/TranslatorHLSL.h" +#include "compiler/translator/VariablePacker.h" + +static bool isInitialized = false; // // This is the platform independent interface between an OGL driver @@ -49,8 +51,11 @@ static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue // int ShInitialize() { - static const bool kInitialized = InitProcess(); - return kInitialized ? 1 : 0; + if (!isInitialized) + { + isInitialized = InitProcess(); + } + return isInitialized ? 1 : 0; } // @@ -58,7 +63,11 @@ int ShInitialize() // int ShFinalize() { - DetachProcess(); + if (isInitialized) + { + DetachProcess(); + isInitialized = false; + } return 1; } @@ -83,14 +92,24 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) resources->ARB_texture_rectangle = 0; resources->EXT_draw_buffers = 0; resources->EXT_frag_depth = 0; + resources->EXT_shader_texture_lod = 0; // Disable highp precision in fragment shader by default. resources->FragmentPrecisionHigh = 0; + // GLSL ES 3.0 constants. + resources->MaxVertexOutputVectors = 16; + resources->MaxFragmentInputVectors = 15; + resources->MinProgramTexelOffset = -8; + resources->MaxProgramTexelOffset = 7; + // Disable name hashing by default. resources->HashFunction = NULL; resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC; + + resources->MaxExpressionComplexity = 256; + resources->MaxCallStackDepth = 256; } // @@ -125,8 +144,25 @@ void ShDestruct(ShHandle handle) DeleteCompiler(base->getAsCompiler()); } +void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString) +{ + if (!handle || !outString) + { + return; + } + + TShHandleBase *base = static_cast<TShHandleBase*>(handle); + TCompiler *compiler = base->getAsCompiler(); + if (!compiler) + { + return; + } + + strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen); + outString[outStringLen - 1] = '\0'; +} // -// Do an actual compile on the given strings. The result is left +// Do an actual compile on the given strings. The result is left // in the given compile object. // // Return: The return value of ShCompile is really boolean, indicating @@ -171,27 +207,27 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) *params = compiler->getUniforms().size(); break; case SH_ACTIVE_UNIFORM_MAX_LENGTH: - *params = 1 + MAX_SYMBOL_NAME_LEN; + *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); break; case SH_ACTIVE_ATTRIBUTES: *params = compiler->getAttribs().size(); break; case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = 1 + MAX_SYMBOL_NAME_LEN; + *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); break; case SH_VARYINGS: *params = compiler->getVaryings().size(); break; case SH_VARYING_MAX_LENGTH: - *params = 1 + MAX_SYMBOL_NAME_LEN; + *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); break; case SH_MAPPED_NAME_MAX_LENGTH: // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to // handle array and struct dereferences. - *params = 1 + MAX_SYMBOL_NAME_LEN; + *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); break; case SH_NAME_MAX_LENGTH: - *params = 1 + MAX_SYMBOL_NAME_LEN; + *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); break; case SH_HASHED_NAME_MAX_LENGTH: if (compiler->getHashFunction() == NULL) { @@ -200,12 +236,22 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) // 64 bits hashing output requires 16 bytes for hex // representation. const char HashedNamePrefix[] = HASHED_NAME_PREFIX; + (void)HashedNamePrefix; *params = 16 + sizeof(HashedNamePrefix); } break; case SH_HASHED_NAMES_COUNT: *params = compiler->getNameMap().size(); break; + case SH_SHADER_VERSION: + *params = compiler->getShaderVersion(); + break; + case SH_RESOURCES_STRING_LENGTH: + *params = compiler->getBuiltInResourcesString().length() + 1; + break; + case SH_OUTPUT_TYPE: + *params = compiler->getOutputType(); + break; default: UNREACHABLE(); } } @@ -295,14 +341,14 @@ void ShGetVariableInfo(const ShHandle handle, // This size must match that queried by // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH // in ShGetInfo, below. - size_t variableLength = 1 + MAX_SYMBOL_NAME_LEN; + size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); ASSERT(checkVariableMaxLengths(handle, variableLength)); strncpy(name, varInfo.name.c_str(), variableLength); name[variableLength - 1] = 0; if (mappedName) { // This size must match that queried by // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below. - size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN; + size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength)); strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength); mappedName[maxMappedNameLength - 1] = 0; @@ -366,6 +412,18 @@ void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params) case SH_ACTIVE_UNIFORMS_ARRAY: *params = (void*)&translator->getUniforms(); break; + case SH_ACTIVE_INTERFACE_BLOCKS_ARRAY: + *params = (void*)&translator->getInterfaceBlocks(); + break; + case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY: + *params = (void*)&translator->getOutputVariables(); + break; + case SH_ACTIVE_ATTRIBUTES_ARRAY: + *params = (void*)&translator->getAttributes(); + break; + case SH_ACTIVE_VARYINGS_ARRAY: + *params = (void*)&translator->getVaryings(); + break; default: UNREACHABLE(); } } diff --git a/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp b/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp new file mode 100644 index 00000000000..aa5933d3e9a --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp @@ -0,0 +1,241 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// +// Symbol table for parsing. Most functionaliy and main ideas +// are documented in the header file. +// + +#if defined(_MSC_VER) +#pragma warning(disable: 4718) +#endif + +#include "compiler/translator/SymbolTable.h" + +#include <stdio.h> +#include <algorithm> + +int TSymbolTable::uniqueIdCounter = 0; + +// +// Functions have buried pointers to delete. +// +TFunction::~TFunction() +{ + for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) + delete (*i).type; +} + +// +// Symbol table levels are a map of pointers to symbols that have to be deleted. +// +TSymbolTableLevel::~TSymbolTableLevel() +{ + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) + delete (*it).second; +} + +bool TSymbolTableLevel::insert(const TString &name, TSymbol &symbol) +{ + symbol.setUniqueId(TSymbolTable::nextUniqueId()); + + // returning true means symbol was added to the table + tInsertResult result = level.insert(tLevelPair(name, &symbol)); + + return result.second; +} + +bool TSymbolTableLevel::insert(TSymbol &symbol) +{ + return insert(symbol.getMangledName(), symbol); +} + +TSymbol *TSymbolTableLevel::find(const TString &name) const +{ + tLevel::const_iterator it = level.find(name); + if (it == level.end()) + return 0; + else + return (*it).second; +} + +// +// Change all function entries in the table with the non-mangled name +// to be related to the provided built-in operation. This is a low +// performance operation, and only intended for symbol tables that +// live across a large number of compiles. +// +void TSymbolTableLevel::relateToOperator(const char *name, TOperator op) +{ + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) + { + if ((*it).second->isFunction()) + { + TFunction *function = static_cast<TFunction*>((*it).second); + if (function->getName() == name) + function->relateToOperator(op); + } + } +} + +// +// Change all function entries in the table with the non-mangled name +// to be related to the provided built-in extension. This is a low +// performance operation, and only intended for symbol tables that +// live across a large number of compiles. +// +void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext) +{ + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) + { + TSymbol *symbol = it->second; + if (symbol->getName() == name) + symbol->relateToExtension(ext); + } +} + +TSymbol::TSymbol(const TSymbol ©Of) +{ + name = NewPoolTString(copyOf.name->c_str()); + uniqueId = copyOf.uniqueId; +} + +TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) +{ + int level = currentLevel(); + TSymbol *symbol; + + do + { + if (level == ESSL3_BUILTINS && shaderVersion != 300) + level--; + if (level == ESSL1_BUILTINS && shaderVersion != 100) + level--; + + symbol = table[level]->find(name); + } + while (symbol == 0 && --level >= 0); + + if (builtIn) + *builtIn = (level <= LAST_BUILTIN_LEVEL); + if (sameScope) + *sameScope = (level == currentLevel()); + + return symbol; +} + +TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) +{ + for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--) + { + if (level == ESSL3_BUILTINS && shaderVersion != 300) + level--; + if (level == ESSL1_BUILTINS && shaderVersion != 100) + level--; + + TSymbol *symbol = table[level]->find(name); + + if (symbol) + return symbol; + } + + return 0; +} + +TSymbolTable::~TSymbolTable() +{ + while (table.size() > 0) + pop(); +} + +void TSymbolTable::insertBuiltIn( + ESymbolLevel level, TType *rvalue, const char *name, + TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5) +{ + if (ptype1->getBasicType() == EbtGSampler2D) + { + bool gvec4 = (rvalue->getBasicType() == EbtGVec4); + insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, + new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, + new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, + new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5); + return; + } + if (ptype1->getBasicType() == EbtGSampler3D) + { + bool gvec4 = (rvalue->getBasicType() == EbtGVec4); + insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, + new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, + new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, + new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5); + return; + } + if (ptype1->getBasicType() == EbtGSamplerCube) + { + bool gvec4 = (rvalue->getBasicType() == EbtGVec4); + insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, + new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, + new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, + new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5); + return; + } + if (ptype1->getBasicType() == EbtGSampler2DArray) + { + bool gvec4 = (rvalue->getBasicType() == EbtGVec4); + insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, + new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, + new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, + new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5); + return; + } + + TFunction *function = new TFunction(NewPoolTString(name), *rvalue); + + TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5}; + for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii) + { + if (types[ii]) + { + TParameter param = {NULL, types[ii]}; + function->addParameter(param); + } + } + + insert(level, *function); +} + +TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) +{ + if (!SupportsPrecision(type)) + return EbpUndefined; + + // unsigned integers use the same precision as signed + TBasicType baseType = (type == EbtUInt) ? EbtInt : type; + + int level = static_cast<int>(precisionStack.size()) - 1; + assert(level >= 0); // Just to be safe. Should not happen. + // If we dont find anything we return this. Should we error check this? + TPrecision prec = EbpUndefined; + while (level >= 0) + { + PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType); + if (it != precisionStack[level]->end()) + { + prec = (*it).second; + break; + } + level--; + } + return prec; +} diff --git a/chromium/third_party/angle/src/compiler/translator/SymbolTable.h b/chromium/third_party/angle/src/compiler/translator/SymbolTable.h new file mode 100644 index 00000000000..3f932a45432 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/SymbolTable.h @@ -0,0 +1,431 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef _SYMBOL_TABLE_INCLUDED_ +#define _SYMBOL_TABLE_INCLUDED_ + +// +// Symbol table for parsing. Has these design characteristics: +// +// * Same symbol table can be used to compile many shaders, to preserve +// effort of creating and loading with the large numbers of built-in +// symbols. +// +// * Name mangling will be used to give each function a unique name +// so that symbol table lookups are never ambiguous. This allows +// a simpler symbol table structure. +// +// * Pushing and popping of scope, so symbol table will really be a stack +// of symbol tables. Searched from the top, with new inserts going into +// the top. +// +// * Constants: Compile time constant symbols will keep their values +// in the symbol table. The parser can substitute constants at parse +// time, including doing constant folding and constant propagation. +// +// * No temporaries: Temporaries made from operations (+, --, .xy, etc.) +// are tracked in the intermediate representation, not the symbol table. +// + +#include <assert.h> + +#include "common/angleutils.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/intermediate.h" + +// Symbol base class. (Can build functions or variables out of these...) +class TSymbol +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TSymbol(const TString *n) + : uniqueId(0), + name(n) + { + } + virtual ~TSymbol() + { + // don't delete name, it's from the pool + } + + const TString &getName() const + { + return *name; + } + virtual const TString &getMangledName() const + { + return getName(); + } + virtual bool isFunction() const + { + return false; + } + virtual bool isVariable() const + { + return false; + } + void setUniqueId(int id) + { + uniqueId = id; + } + int getUniqueId() const + { + return uniqueId; + } + void relateToExtension(const TString &ext) + { + extension = ext; + } + const TString &getExtension() const + { + return extension; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TSymbol); + + int uniqueId; // For real comparing during code generation + const TString *name; + TString extension; +}; + +// Variable class, meaning a symbol that's not a function. +// +// There could be a separate class heirarchy for Constant variables; +// Only one of int, bool, or float, (or none) is correct for +// any particular use, but it's easy to do this way, and doesn't +// seem worth having separate classes, and "getConst" can't simply return +// different values for different types polymorphically, so this is +// just simple and pragmatic. +class TVariable : public TSymbol +{ + public: + TVariable(const TString *name, const TType &t, bool uT = false) + : TSymbol(name), + type(t), + userType(uT), + unionArray(0) + { + } + virtual ~TVariable() + { + } + virtual bool isVariable() const + { + return true; + } + TType &getType() + { + return type; + } + const TType &getType() const + { + return type; + } + bool isUserType() const + { + return userType; + } + void setQualifier(TQualifier qualifier) + { + type.setQualifier(qualifier); + } + + ConstantUnion *getConstPointer() + { + if (!unionArray) + unionArray = new ConstantUnion[type.getObjectSize()]; + + return unionArray; + } + + ConstantUnion *getConstPointer() const + { + return unionArray; + } + + void shareConstPointer(ConstantUnion *constArray) + { + if (unionArray == constArray) + return; + + delete[] unionArray; + unionArray = constArray; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TVariable); + + TType type; + bool userType; + // we are assuming that Pool Allocator will free the memory + // allocated to unionArray when this object is destroyed. + ConstantUnion *unionArray; +}; + +// The function sub-class of symbols and the parser will need to +// share this definition of a function parameter. +struct TParameter +{ + TString *name; + TType *type; +}; + +// The function sub-class of a symbol. +class TFunction : public TSymbol +{ + public: + TFunction(TOperator o) + : TSymbol(0), + returnType(TType(EbtVoid, EbpUndefined)), + op(o), + defined(false) + { + } + TFunction(const TString *name, TType &retType, TOperator tOp = EOpNull) + : TSymbol(name), + returnType(retType), + mangledName(TFunction::mangleName(*name)), + op(tOp), + defined(false) + { + } + virtual ~TFunction(); + virtual bool isFunction() const + { + return true; + } + + static TString mangleName(const TString &name) + { + return name + '('; + } + static TString unmangleName(const TString &mangledName) + { + return TString(mangledName.c_str(), mangledName.find_first_of('(')); + } + + void addParameter(TParameter &p) + { + parameters.push_back(p); + mangledName = mangledName + p.type->getMangledName(); + } + + const TString &getMangledName() const + { + return mangledName; + } + const TType &getReturnType() const + { + return returnType; + } + + void relateToOperator(TOperator o) + { + op = o; + } + TOperator getBuiltInOp() const + { + return op; + } + + void setDefined() + { + defined = true; + } + bool isDefined() + { + return defined; + } + + size_t getParamCount() const + { + return parameters.size(); + } + const TParameter &getParam(size_t i) const + { + return parameters[i]; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TFunction); + + typedef TVector<TParameter> TParamList; + TParamList parameters; + TType returnType; + TString mangledName; + TOperator op; + bool defined; +}; + +// Interface block name sub-symbol +class TInterfaceBlockName : public TSymbol +{ + public: + TInterfaceBlockName(const TString *name) + : TSymbol(name) + { + } + + virtual ~TInterfaceBlockName() + { + } +}; + +class TSymbolTableLevel +{ + public: + typedef TMap<TString, TSymbol *> tLevel; + typedef tLevel::const_iterator const_iterator; + typedef const tLevel::value_type tLevelPair; + typedef std::pair<tLevel::iterator, bool> tInsertResult; + + TSymbolTableLevel() + { + } + ~TSymbolTableLevel(); + + bool insert(const TString &name, TSymbol &symbol); + bool insert(TSymbol &symbol); + + TSymbol *find(const TString &name) const; + + void relateToOperator(const char *name, TOperator op); + void relateToExtension(const char *name, const TString &ext); + + protected: + tLevel level; + static int uniqueId; // for unique identification in code generation +}; + +enum ESymbolLevel +{ + COMMON_BUILTINS = 0, + ESSL1_BUILTINS = 1, + ESSL3_BUILTINS = 2, + LAST_BUILTIN_LEVEL = ESSL3_BUILTINS, + GLOBAL_LEVEL = 3 +}; + +class TSymbolTable +{ + public: + TSymbolTable() + { + // The symbol table cannot be used until push() is called, but + // the lack of an initial call to push() can be used to detect + // that the symbol table has not been preloaded with built-ins. + } + + ~TSymbolTable(); + + // When the symbol table is initialized with the built-ins, there should + // 'push' calls, so that built-ins are at level 0 and the shader + // globals are at level 1. + bool isEmpty() + { + return table.empty(); + } + bool atBuiltInLevel() + { + return currentLevel() <= LAST_BUILTIN_LEVEL; + } + bool atGlobalLevel() + { + return currentLevel() <= GLOBAL_LEVEL; + } + void push() + { + table.push_back(new TSymbolTableLevel); + precisionStack.push_back(new PrecisionStackLevel); + } + + void pop() + { + delete table.back(); + table.pop_back(); + + delete precisionStack.back(); + precisionStack.pop_back(); + } + + bool declare(TSymbol &symbol) + { + return insert(currentLevel(), symbol); + } + + bool insert(ESymbolLevel level, TSymbol &symbol) + { + return table[level]->insert(symbol); + } + + bool insertConstInt(ESymbolLevel level, const char *name, int value) + { + TVariable *constant = new TVariable( + NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + constant->getConstPointer()->setIConst(value); + return insert(level, *constant); + } + + void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, + TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, + TType *ptype4 = 0, TType *ptype5 = 0); + + TSymbol *find(const TString &name, int shaderVersion, + bool *builtIn = NULL, bool *sameScope = NULL); + TSymbol *findBuiltIn(const TString &name, int shaderVersion); + + TSymbolTableLevel *getOuterLevel() + { + assert(currentLevel() >= 1); + return table[currentLevel() - 1]; + } + + void relateToOperator(ESymbolLevel level, const char *name, TOperator op) + { + table[level]->relateToOperator(name, op); + } + void relateToExtension(ESymbolLevel level, const char *name, const TString &ext) + { + table[level]->relateToExtension(name, ext); + } + void dump(TInfoSink &infoSink) const; + + bool setDefaultPrecision(const TPublicType &type, TPrecision prec) + { + if (!SupportsPrecision(type.type)) + return false; + if (type.isAggregate()) + return false; // Not allowed to set for aggregate types + int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; + // Uses map operator [], overwrites the current value + (*precisionStack[indexOfLastElement])[type.type] = prec; + return true; + } + + // Searches down the precisionStack for a precision qualifier + // for the specified TBasicType + TPrecision getDefaultPrecision(TBasicType type); + + static int nextUniqueId() + { + return ++uniqueIdCounter; + } + + private: + ESymbolLevel currentLevel() const + { + return static_cast<ESymbolLevel>(table.size() - 1); + } + + std::vector<TSymbolTableLevel *> table; + typedef TMap<TBasicType, TPrecision> PrecisionStackLevel; + std::vector< PrecisionStackLevel *> precisionStack; + + static int uniqueIdCounter; +}; + +#endif // _SYMBOL_TABLE_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/TranslatorESSL.cpp b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.cpp index 2900f8a8ede..c956e29c5be 100644 --- a/chromium/third_party/angle/src/compiler/TranslatorESSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.cpp @@ -1,15 +1,15 @@ // -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/TranslatorESSL.h" +#include "compiler/translator/TranslatorESSL.h" -#include "compiler/OutputESSL.h" +#include "compiler/translator/OutputESSL.h" TranslatorESSL::TranslatorESSL(ShShaderType type, ShShaderSpec spec) - : TCompiler(type, spec) { + : TCompiler(type, spec, SH_ESSL_OUTPUT) { } void TranslatorESSL::translate(TIntermNode* root) { @@ -26,7 +26,7 @@ void TranslatorESSL::translate(TIntermNode* root) { getArrayBoundsClamper().OutputClampingFunctionDefinition(sink); // Write translated shader. - TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable()); + TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion()); root->traverse(&outputESSL); } diff --git a/chromium/third_party/angle/src/compiler/TranslatorESSL.h b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.h index a1196bd0013..e18f3c25ec8 100644 --- a/chromium/third_party/angle/src/compiler/TranslatorESSL.h +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.h @@ -7,7 +7,7 @@ #ifndef COMPILER_TRANSLATORESSL_H_ #define COMPILER_TRANSLATORESSL_H_ -#include "compiler/ShHandle.h" +#include "compiler/translator/ShHandle.h" class TranslatorESSL : public TCompiler { public: diff --git a/chromium/third_party/angle/src/compiler/TranslatorGLSL.cpp b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.cpp index 7ca4341dcde..749d8377f0c 100644 --- a/chromium/third_party/angle/src/compiler/TranslatorGLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.cpp @@ -1,13 +1,13 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/TranslatorGLSL.h" +#include "compiler/translator/TranslatorGLSL.h" -#include "compiler/OutputGLSL.h" -#include "compiler/VersionGLSL.h" +#include "compiler/translator/OutputGLSL.h" +#include "compiler/translator/VersionGLSL.h" static void writeVersion(ShShaderType type, TIntermNode* root, TInfoSinkBase& sink) { @@ -22,7 +22,7 @@ static void writeVersion(ShShaderType type, TIntermNode* root, } TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec) - : TCompiler(type, spec) { + : TCompiler(type, spec, SH_GLSL_OUTPUT) { } void TranslatorGLSL::translate(TIntermNode* root) { @@ -31,6 +31,9 @@ void TranslatorGLSL::translate(TIntermNode* root) { // Write GLSL version. writeVersion(getShaderType(), root, sink); + // Write extension behaviour as needed + writeExtensionBehavior(); + // Write emulated built-in functions if needed. getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition( sink, false); @@ -39,6 +42,23 @@ void TranslatorGLSL::translate(TIntermNode* root) { getArrayBoundsClamper().OutputClampingFunctionDefinition(sink); // Write translated shader. - TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable()); + TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion()); root->traverse(&outputGLSL); } + +void TranslatorGLSL::writeExtensionBehavior() { + TInfoSinkBase& sink = getInfoSink().obj; + const TExtensionBehavior& extensionBehavior = getExtensionBehavior(); + for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin(); + iter != extensionBehavior.end(); ++iter) { + if (iter->second == EBhUndefined) + continue; + + // For GLSL output, we don't need to emit most extensions explicitly, + // but some we need to translate. + if (iter->first == "GL_EXT_shader_texture_lod") { + sink << "#extension GL_ARB_shader_texture_lod : " + << getBehaviorString(iter->second) << "\n"; + } + } +} diff --git a/chromium/third_party/angle/src/compiler/TranslatorGLSL.h b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.h index c2ce06d192f..1e16b2605e4 100644 --- a/chromium/third_party/angle/src/compiler/TranslatorGLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.h @@ -7,7 +7,7 @@ #ifndef COMPILER_TRANSLATORGLSL_H_ #define COMPILER_TRANSLATORGLSL_H_ -#include "compiler/ShHandle.h" +#include "compiler/translator/ShHandle.h" class TranslatorGLSL : public TCompiler { public: @@ -15,6 +15,9 @@ public: protected: virtual void translate(TIntermNode* root); + +private: + void writeExtensionBehavior(); }; #endif // COMPILER_TRANSLATORGLSL_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp new file mode 100644 index 00000000000..da6f9801ad0 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp @@ -0,0 +1,29 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/TranslatorHLSL.h" + +#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/OutputHLSL.h" + +TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output) + : TCompiler(type, spec, output) +{ +} + +void TranslatorHLSL::translate(TIntermNode *root) +{ + TParseContext& parseContext = *GetGlobalParseContext(); + sh::OutputHLSL outputHLSL(parseContext, getResources(), getOutputType()); + + outputHLSL.output(); + + mActiveUniforms = outputHLSL.getUniforms(); + mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks(); + mActiveOutputVariables = outputHLSL.getOutputVariables(); + mActiveAttributes = outputHLSL.getAttributes(); + mActiveVaryings = outputHLSL.getVaryings(); +} diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h new file mode 100644 index 00000000000..8b16587b6b1 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATORHLSL_H_ +#define COMPILER_TRANSLATORHLSL_H_ + +#include "compiler/translator/ShHandle.h" +#include "common/shadervars.h" + +class TranslatorHLSL : public TCompiler { +public: + TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output); + + virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; } + const std::vector<gl::Uniform> &getUniforms() { return mActiveUniforms; } + const std::vector<gl::InterfaceBlock> &getInterfaceBlocks() const { return mActiveInterfaceBlocks; } + const std::vector<gl::Attribute> &getOutputVariables() { return mActiveOutputVariables; } + const std::vector<gl::Attribute> &getAttributes() { return mActiveAttributes; } + const std::vector<gl::Varying> &getVaryings() { return mActiveVaryings; } + +protected: + virtual void translate(TIntermNode* root); + + std::vector<gl::Uniform> mActiveUniforms; + std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks; + std::vector<gl::Attribute> mActiveOutputVariables; + std::vector<gl::Attribute> mActiveAttributes; + std::vector<gl::Varying> mActiveVaryings; +}; + +#endif // COMPILER_TRANSLATORHLSL_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/Types.cpp b/chromium/third_party/angle/src/compiler/translator/Types.cpp new file mode 100644 index 00000000000..4763920f86e --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/Types.cpp @@ -0,0 +1,250 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#if defined(_MSC_VER) +#pragma warning(disable: 4718) +#endif + +#include "compiler/translator/Types.h" + +#include <algorithm> +#include <climits> + +TType::TType(const TPublicType &p) + : type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier), + primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), + interfaceBlock(0), structure(0) +{ + if (p.userDef) + structure = p.userDef->getStruct(); +} + +bool TType::equals(const TType &other) const +{ + if (type != other.type || precision != other.precision || + primarySize != other.primarySize || secondarySize != other.secondarySize || + array != other.array || (array && arraySize != other.arraySize) || + interfaceBlock != other.interfaceBlock || structure != other.structure) + { + return false; + } + if (interfaceBlock && !interfaceBlock->equals(*(other.interfaceBlock))) + return false; + if (structure && !structure->equals(*(other.structure))) + return false; + return true; +} + +bool TField::equals(const TField &other) const +{ + ASSERT(mType && mName); + ASSERT(other.mType && other.mName); + return mType->equals(*(other.mType)) && *mName == *(other.mName); +} + +bool TFieldListCollection::equals(const TFieldListCollection &other) const +{ + ASSERT(mName && mFields); + ASSERT(other.mName && other.mFields); + if (*mName != *(other.mName)) + return false; + if (mFields->size() != other.mFields->size()) + return false; + for (size_t ii = 0; ii < mFields->size(); ++ii) + { + ASSERT((*mFields)[ii] && (*(other.mFields))[ii]); + if (!(*mFields)[ii]->equals(*((*(other.mFields))[ii]))) + return false; + } + return true; +} + +bool TStructure::equals(const TStructure &other) const +{ + return TFieldListCollection::equals(other); +} + +bool TInterfaceBlock::equals(const TInterfaceBlock &other) const +{ + if (!TFieldListCollection::equals(other)) + return false; + // TODO(zmo): do we need to consider mBlockStorage and mMatrixPacking? + return mArraySize == other.mArraySize; +} + +// +// Recursively generate mangled names. +// +TString TType::buildMangledName() const +{ + TString mangledName; + if (isMatrix()) + mangledName += 'm'; + else if (isVector()) + mangledName += 'v'; + + switch (type) + { + case EbtFloat: + mangledName += 'f'; + break; + case EbtInt: + mangledName += 'i'; + break; + case EbtUInt: + mangledName += 'u'; + break; + case EbtBool: + mangledName += 'b'; + break; + case EbtSampler2D: + mangledName += "s2"; + break; + case EbtSampler3D: + mangledName += "s3"; + break; + case EbtSamplerCube: + mangledName += "sC"; + break; + case EbtSampler2DArray: + mangledName += "s2a"; + break; + case EbtSamplerExternalOES: + mangledName += "sext"; + break; + case EbtSampler2DRect: + mangledName += "s2r"; + break; + case EbtISampler2D: + mangledName += "is2"; + break; + case EbtISampler3D: + mangledName += "is3"; + break; + case EbtISamplerCube: + mangledName += "isC"; + break; + case EbtISampler2DArray: + mangledName += "is2a"; + break; + case EbtUSampler2D: + mangledName += "us2"; + break; + case EbtUSampler3D: + mangledName += "us3"; + break; + case EbtUSamplerCube: + mangledName += "usC"; + break; + case EbtUSampler2DArray: + mangledName += "us2a"; + break; + case EbtSampler2DShadow: + mangledName += "s2s"; + break; + case EbtSamplerCubeShadow: + mangledName += "sCs"; + break; + case EbtSampler2DArrayShadow: + mangledName += "s2as"; + break; + case EbtStruct: + mangledName += structure->mangledName(); + break; + case EbtInterfaceBlock: + mangledName += interfaceBlock->mangledName(); + break; + default: + UNREACHABLE(); + } + + if (isMatrix()) + { + mangledName += static_cast<char>('0' + getCols()); + mangledName += static_cast<char>('x'); + mangledName += static_cast<char>('0' + getRows()); + } + else + { + mangledName += static_cast<char>('0' + getNominalSize()); + } + + if (isArray()) + { + char buf[20]; + snprintf(buf, sizeof(buf), "%d", arraySize); + mangledName += '['; + mangledName += buf; + mangledName += ']'; + } + return mangledName; +} + +size_t TType::getObjectSize() const +{ + size_t totalSize; + + if (getBasicType() == EbtStruct) + totalSize = structure->objectSize(); + else + totalSize = primarySize * secondarySize; + + if (isArray()) + { + size_t arraySize = getArraySize(); + if (arraySize > INT_MAX / totalSize) + totalSize = INT_MAX; + else + totalSize *= arraySize; + } + + return totalSize; +} + +bool TStructure::containsArrays() const +{ + for (size_t i = 0; i < mFields->size(); ++i) + { + const TType *fieldType = (*mFields)[i]->type(); + if (fieldType->isArray() || fieldType->isStructureContainingArrays()) + return true; + } + return false; +} + +TString TFieldListCollection::buildMangledName() const +{ + TString mangledName(mangledNamePrefix()); + mangledName += *mName; + for (size_t i = 0; i < mFields->size(); ++i) + { + mangledName += '-'; + mangledName += (*mFields)[i]->type()->getMangledName(); + } + return mangledName; +} + +size_t TFieldListCollection::calculateObjectSize() const +{ + size_t size = 0; + for (size_t i = 0; i < mFields->size(); ++i) + { + size_t fieldSize = (*mFields)[i]->type()->getObjectSize(); + if (fieldSize > INT_MAX - size) + size = INT_MAX; + else + size += fieldSize; + } + return size; +} + +int TStructure::calculateDeepestNesting() const +{ + int maxNesting = 0; + for (size_t i = 0; i < mFields->size(); ++i) + maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting()); + return 1 + maxNesting; +} diff --git a/chromium/third_party/angle/src/compiler/translator/Types.h b/chromium/third_party/angle/src/compiler/translator/Types.h new file mode 100644 index 00000000000..76297202a56 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/Types.h @@ -0,0 +1,586 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef _TYPES_INCLUDED +#define _TYPES_INCLUDED + +#include "common/angleutils.h" + +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Common.h" +#include "compiler/translator/compilerdebug.h" + +struct TPublicType; +class TType; +class TSymbol; + +class TField +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TField(TType *type, TString *name, const TSourceLoc &line) + : mType(type), + mName(name), + mLine(line) + { + } + + // TODO(alokp): We should only return const type. + // Fix it by tweaking grammar. + TType *type() + { + return mType; + } + const TType *type() const + { + return mType; + } + + const TString &name() const + { + return *mName; + } + const TSourceLoc &line() const + { + return mLine; + } + + bool equals(const TField &other) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TField); + TType *mType; + TString *mName; + TSourceLoc mLine; +}; + +typedef TVector<TField *> TFieldList; +inline TFieldList *NewPoolTFieldList() +{ + void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList)); + return new(memory) TFieldList; +} + +class TFieldListCollection +{ + public: + const TString &name() const + { + return *mName; + } + const TFieldList &fields() const + { + return *mFields; + } + + const TString &mangledName() const + { + if (mMangledName.empty()) + mMangledName = buildMangledName(); + return mMangledName; + } + size_t objectSize() const + { + if (mObjectSize == 0) + mObjectSize = calculateObjectSize(); + return mObjectSize; + }; + + protected: + TFieldListCollection(const TString *name, TFieldList *fields) + : mName(name), + mFields(fields), + mObjectSize(0) + { + } + TString buildMangledName() const; + size_t calculateObjectSize() const; + virtual TString mangledNamePrefix() const = 0; + + bool equals(const TFieldListCollection &other) const; + + const TString *mName; + TFieldList *mFields; + + mutable TString mMangledName; + mutable size_t mObjectSize; +}; + +// May also represent interface blocks +class TStructure : public TFieldListCollection +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TStructure(const TString *name, TFieldList *fields) + : TFieldListCollection(name, fields), + mDeepestNesting(0), + mUniqueId(0) + { + } + + int deepestNesting() const + { + if (mDeepestNesting == 0) + mDeepestNesting = calculateDeepestNesting(); + return mDeepestNesting; + } + bool containsArrays() const; + + bool equals(const TStructure &other) const; + + void setUniqueId(int uniqueId) + { + mUniqueId = uniqueId; + } + + int uniqueId() const + { + ASSERT(mUniqueId != 0); + return mUniqueId; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TStructure); + virtual TString mangledNamePrefix() const + { + return "struct-"; + } + int calculateDeepestNesting() const; + + mutable int mDeepestNesting; + int mUniqueId; +}; + +class TInterfaceBlock : public TFieldListCollection +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName, + int arraySize, const TLayoutQualifier &layoutQualifier) + : TFieldListCollection(name, fields), + mInstanceName(instanceName), + mArraySize(arraySize), + mBlockStorage(layoutQualifier.blockStorage), + mMatrixPacking(layoutQualifier.matrixPacking) + { + } + + const TString &instanceName() const + { + return *mInstanceName; + } + bool hasInstanceName() const + { + return mInstanceName != NULL; + } + bool isArray() const + { + return mArraySize > 0; + } + int arraySize() const + { + return mArraySize; + } + TLayoutBlockStorage blockStorage() const + { + return mBlockStorage; + } + TLayoutMatrixPacking matrixPacking() const + { + return mMatrixPacking; + } + + bool equals(const TInterfaceBlock &other) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock); + virtual TString mangledNamePrefix() const + { + return "iblock-"; + } + + const TString *mInstanceName; // for interface block instance names + int mArraySize; // 0 if not an array + TLayoutBlockStorage mBlockStorage; + TLayoutMatrixPacking mMatrixPacking; +}; + +// +// Base class for things that have a type. +// +class TType +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TType() + { + } + TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) + : type(t), precision(EbpUndefined), qualifier(EvqGlobal), + layoutQualifier(TLayoutQualifier::create()), + primarySize(ps), secondarySize(ss), array(false), arraySize(0), + interfaceBlock(0), structure(0) + { + } + TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, + unsigned char ps = 1, unsigned char ss = 1, bool a = false) + : type(t), precision(p), qualifier(q), + layoutQualifier(TLayoutQualifier::create()), + primarySize(ps), secondarySize(ss), array(a), arraySize(0), + interfaceBlock(0), structure(0) + { + } + explicit TType(const TPublicType &p); + TType(TStructure *userDef, TPrecision p = EbpUndefined) + : type(EbtStruct), precision(p), qualifier(EvqTemporary), + layoutQualifier(TLayoutQualifier::create()), + primarySize(1), secondarySize(1), array(false), arraySize(0), + interfaceBlock(0), structure(userDef) + { + } + TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn, + TLayoutQualifier layoutQualifierIn, int arraySizeIn) + : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), + layoutQualifier(layoutQualifierIn), + primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), + interfaceBlock(interfaceBlockIn), structure(0) + { + } + + TBasicType getBasicType() const + { + return type; + } + void setBasicType(TBasicType t) + { + type = t; + } + + TPrecision getPrecision() const + { + return precision; + } + void setPrecision(TPrecision p) + { + precision = p; + } + + TQualifier getQualifier() const + { + return qualifier; + } + void setQualifier(TQualifier q) + { + qualifier = q; + } + + TLayoutQualifier getLayoutQualifier() const + { + return layoutQualifier; + } + void setLayoutQualifier(TLayoutQualifier lq) + { + layoutQualifier = lq; + } + + int getNominalSize() const + { + return primarySize; + } + int getSecondarySize() const + { + return secondarySize; + } + int getCols() const + { + ASSERT(isMatrix()); + return primarySize; + } + int getRows() const + { + ASSERT(isMatrix()); + return secondarySize; + } + void setPrimarySize(unsigned char ps) + { + primarySize = ps; + } + void setSecondarySize(unsigned char ss) + { + secondarySize = ss; + } + + // Full size of single instance of type + size_t getObjectSize() const; + + bool isMatrix() const + { + return primarySize > 1 && secondarySize > 1; + } + bool isArray() const + { + return array ? true : false; + } + int getArraySize() const + { + return arraySize; + } + void setArraySize(int s) + { + array = true; + arraySize = s; + } + void clearArrayness() + { + array = false; + arraySize = 0; + } + + TInterfaceBlock *getInterfaceBlock() const + { + return interfaceBlock; + } + void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) + { + interfaceBlock = interfaceBlockIn; + } + bool isInterfaceBlock() const + { + return type == EbtInterfaceBlock; + } + + bool isVector() const + { + return primarySize > 1 && secondarySize == 1; + } + bool isScalar() const + { + return primarySize == 1 && secondarySize == 1 && !structure; + } + bool isScalarInt() const + { + return isScalar() && (type == EbtInt || type == EbtUInt); + } + + TStructure *getStruct() const + { + return structure; + } + void setStruct(TStructure *s) + { + structure = s; + } + + const TString &getMangledName() + { + if (mangled.empty()) + { + mangled = buildMangledName(); + mangled += ';'; + } + + return mangled; + } + + // This is different from operator== as we also compare + // precision here. + bool equals(const TType &other) const; + + bool sameElementType(const TType &right) const + { + return type == right.type && + primarySize == right.primarySize && + secondarySize == right.secondarySize && + structure == right.structure; + } + bool operator==(const TType &right) const + { + return type == right.type && + primarySize == right.primarySize && + secondarySize == right.secondarySize && + array == right.array && (!array || arraySize == right.arraySize) && + structure == right.structure; + // don't check the qualifier, it's not ever what's being sought after + } + bool operator!=(const TType &right) const + { + return !operator==(right); + } + bool operator<(const TType &right) const + { + if (type != right.type) + return type < right.type; + if (primarySize != right.primarySize) + return primarySize < right.primarySize; + if (secondarySize != right.secondarySize) + return secondarySize < right.secondarySize; + if (array != right.array) + return array < right.array; + if (arraySize != right.arraySize) + return arraySize < right.arraySize; + if (structure != right.structure) + return structure < right.structure; + + return false; + } + + const char *getBasicString() const + { + return ::getBasicString(type); + } + const char *getPrecisionString() const + { + return ::getPrecisionString(precision); + } + const char *getQualifierString() const + { + return ::getQualifierString(qualifier); + } + TString getCompleteString() const; + + // If this type is a struct, returns the deepest struct nesting of + // any field in the struct. For example: + // struct nesting1 { + // vec4 position; + // }; + // struct nesting2 { + // nesting1 field1; + // vec4 field2; + // }; + // For type "nesting2", this method would return 2 -- the number + // of structures through which indirection must occur to reach the + // deepest field (nesting2.field1.position). + int getDeepestStructNesting() const + { + return structure ? structure->deepestNesting() : 0; + } + + bool isStructureContainingArrays() const + { + return structure ? structure->containsArrays() : false; + } + + protected: + TString buildMangledName() const; + size_t getStructSize() const; + void computeDeepestStructNesting(); + + TBasicType type; + TPrecision precision; + TQualifier qualifier; + TLayoutQualifier layoutQualifier; + unsigned char primarySize; // size of vector or cols matrix + unsigned char secondarySize; // rows of a matrix + bool array; + int arraySize; + + // 0 unless this is an interface block, or interface block member variable + TInterfaceBlock *interfaceBlock; + + // 0 unless this is a struct + TStructure *structure; + + mutable TString mangled; +}; + +// +// This is a workaround for a problem with the yacc stack, It can't have +// types that it thinks have non-trivial constructors. It should +// just be used while recognizing the grammar, not anything else. Pointers +// could be used, but also trying to avoid lots of memory management overhead. +// +// Not as bad as it looks, there is no actual assumption that the fields +// match up or are name the same or anything like that. +// +struct TPublicType +{ + TBasicType type; + TLayoutQualifier layoutQualifier; + TQualifier qualifier; + TPrecision precision; + unsigned char primarySize; // size of vector or cols of matrix + unsigned char secondarySize; // rows of matrix + bool array; + int arraySize; + TType *userDef; + TSourceLoc line; + + void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln) + { + type = bt; + layoutQualifier = TLayoutQualifier::create(); + qualifier = q; + precision = EbpUndefined; + primarySize = 1; + secondarySize = 1; + array = false; + arraySize = 0; + userDef = 0; + line = ln; + } + + void setAggregate(unsigned char size) + { + primarySize = size; + } + + void setMatrix(unsigned char c, unsigned char r) + { + ASSERT(c > 1 && r > 1 && c <= 4 && r <= 4); + primarySize = c; + secondarySize = r; + } + + void setArray(bool a, int s = 0) + { + array = a; + arraySize = s; + } + + bool isStructureContainingArrays() const + { + if (!userDef) + { + return false; + } + + return userDef->isStructureContainingArrays(); + } + + bool isMatrix() const + { + return primarySize > 1 && secondarySize > 1; + } + + bool isVector() const + { + return primarySize > 1 && secondarySize == 1; + } + + int getCols() const + { + ASSERT(isMatrix()); + return primarySize; + } + + int getRows() const + { + ASSERT(isMatrix()); + return secondarySize; + } + + int getNominalSize() const + { + return primarySize; + } + + bool isAggregate() const + { + return array || isMatrix() || isVector(); + } +}; + +#endif // _TYPES_INCLUDED_ diff --git a/chromium/third_party/angle/src/compiler/UnfoldShortCircuit.cpp b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp index 5cfdd3230e4..b7826119aea 100644 --- a/chromium/third_party/angle/src/compiler/UnfoldShortCircuit.cpp +++ b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp @@ -8,10 +8,10 @@ // the original expression. // -#include "compiler/UnfoldShortCircuit.h" +#include "compiler/translator/UnfoldShortCircuit.h" -#include "compiler/InfoSink.h" -#include "compiler/OutputHLSL.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/OutputHLSL.h" namespace sh { diff --git a/chromium/third_party/angle/src/compiler/UnfoldShortCircuit.h b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuit.h index ae2989fa4ab..1e416bc04c1 100644 --- a/chromium/third_party/angle/src/compiler/UnfoldShortCircuit.h +++ b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuit.h @@ -9,8 +9,8 @@ #ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_ #define COMPILER_UNFOLDSHORTCIRCUIT_H_ -#include "compiler/intermediate.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/intermediate.h" +#include "compiler/translator/ParseContext.h" namespace sh { diff --git a/chromium/third_party/angle/src/compiler/UnfoldShortCircuitAST.cpp b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp index a19bceaeb43..29c4397d561 100644 --- a/chromium/third_party/angle/src/compiler/UnfoldShortCircuitAST.cpp +++ b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/UnfoldShortCircuitAST.h" +#include "compiler/translator/UnfoldShortCircuitAST.h" namespace { diff --git a/chromium/third_party/angle/src/compiler/UnfoldShortCircuitAST.h b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.h index cfc50066485..24c14a60e37 100644 --- a/chromium/third_party/angle/src/compiler/UnfoldShortCircuitAST.h +++ b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.h @@ -11,7 +11,7 @@ #define COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_ #include "common/angleutils.h" -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" // This traverser identifies all the short circuit binary nodes that need to // be replaced, and creates the corresponding replacement nodes. However, diff --git a/chromium/third_party/angle/src/compiler/ValidateLimitations.cpp b/chromium/third_party/angle/src/compiler/translator/ValidateLimitations.cpp index 64969c489fa..e96a777cee3 100644 --- a/chromium/third_party/angle/src/compiler/ValidateLimitations.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ValidateLimitations.cpp @@ -1,33 +1,16 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/ValidateLimitations.h" -#include "compiler/InfoSink.h" -#include "compiler/InitializeParseContext.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/ValidateLimitations.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/ParseContext.h" -namespace { -bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) { - for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) { - if (i->index.id == symbol->getId()) - return true; - } - return false; -} - -void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) { - for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) { - if (i->index.id == symbol->getId()) { - ASSERT(i->loop != NULL); - i->loop->setUnrollFlag(true); - return; - } - } - UNREACHABLE(); -} +namespace +{ // Traverses a node to check if it represents a constant index expression. // Definition: @@ -38,110 +21,60 @@ void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) { // - Constant expressions // - Loop indices as defined in section 4 // - Expressions composed of both of the above -class ValidateConstIndexExpr : public TIntermTraverser { -public: - ValidateConstIndexExpr(const TLoopStack& stack) +class ValidateConstIndexExpr : public TIntermTraverser +{ + public: + ValidateConstIndexExpr(TLoopStack& stack) : mValid(true), mLoopStack(stack) {} // Returns true if the parsed node represents a constant index expression. bool isValid() const { return mValid; } - virtual void visitSymbol(TIntermSymbol* symbol) { + virtual void visitSymbol(TIntermSymbol *symbol) + { // Only constants and loop indices are allowed in a // constant index expression. - if (mValid) { + if (mValid) + { mValid = (symbol->getQualifier() == EvqConst) || - IsLoopIndex(symbol, mLoopStack); + (mLoopStack.findLoop(symbol)); } } -private: + private: bool mValid; - const TLoopStack& mLoopStack; -}; - -// Traverses a node to check if it uses a loop index. -// If an int loop index is used in its body as a sampler array index, -// mark the loop for unroll. -class ValidateLoopIndexExpr : public TIntermTraverser { -public: - ValidateLoopIndexExpr(TLoopStack& stack) - : mUsesFloatLoopIndex(false), - mUsesIntLoopIndex(false), - mLoopStack(stack) {} - - bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; } - bool usesIntLoopIndex() const { return mUsesIntLoopIndex; } - - virtual void visitSymbol(TIntermSymbol* symbol) { - if (IsLoopIndex(symbol, mLoopStack)) { - switch (symbol->getBasicType()) { - case EbtFloat: - mUsesFloatLoopIndex = true; - break; - case EbtInt: - mUsesIntLoopIndex = true; - MarkLoopForUnroll(symbol, mLoopStack); - break; - default: - UNREACHABLE(); - } - } - } - -private: - bool mUsesFloatLoopIndex; - bool mUsesIntLoopIndex; TLoopStack& mLoopStack; }; -} // namespace + +} // namespace anonymous ValidateLimitations::ValidateLimitations(ShShaderType shaderType, - TInfoSinkBase& sink) + TInfoSinkBase &sink) : mShaderType(shaderType), mSink(sink), mNumErrors(0) { } -bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node) +bool ValidateLimitations::visitBinary(Visit, TIntermBinary *node) { // Check if loop index is modified in the loop body. validateOperation(node, node->getLeft()); // Check indexing. - switch (node->getOp()) { + switch (node->getOp()) + { case EOpIndexDirect: - validateIndexing(node); - break; case EOpIndexIndirect: -#if defined(__APPLE__) - // Loop unrolling is a work-around for a Mac Cg compiler bug where it - // crashes when a sampler array's index is also the loop index. - // Once Apple fixes this bug, we should remove the code in this CL. - // See http://codereview.appspot.com/4331048/. - if ((node->getLeft() != NULL) && (node->getRight() != NULL) && - (node->getLeft()->getAsSymbolNode())) { - TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode(); - if (IsSampler(symbol->getBasicType()) && symbol->isArray()) { - ValidateLoopIndexExpr validate(mLoopStack); - node->getRight()->traverse(&validate); - if (validate.usesFloatLoopIndex()) { - error(node->getLine(), - "sampler array index is float loop index", - "for"); - } - } - } -#endif validateIndexing(node); break; - default: break; + default: + break; } return true; } -bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node) +bool ValidateLimitations::visitUnary(Visit, TIntermUnary *node) { // Check if loop index is modified in the loop body. validateOperation(node, node->getOperand()); @@ -149,7 +82,7 @@ bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node) return true; } -bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node) +bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate *node) { switch (node->getOp()) { case EOpFunctionCall: @@ -161,22 +94,20 @@ bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node) return true; } -bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node) +bool ValidateLimitations::visitLoop(Visit, TIntermLoop *node) { if (!validateLoopType(node)) return false; - TLoopInfo info; - memset(&info, 0, sizeof(TLoopInfo)); - info.loop = node; - if (!validateForLoopHeader(node, &info)) + if (!validateForLoopHeader(node)) return false; - TIntermNode* body = node->getBody(); - if (body != NULL) { - mLoopStack.push_back(info); + TIntermNode *body = node->getBody(); + if (body != NULL) + { + mLoopStack.push(node); body->traverse(this); - mLoopStack.pop_back(); + mLoopStack.pop(); } // The loop is fully processed - no need to visit children. @@ -184,7 +115,7 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node) } void ValidateLimitations::error(TSourceLoc loc, - const char *reason, const char* token) + const char *reason, const char *token) { mSink.prefix(EPrefixError); mSink.location(loc); @@ -197,12 +128,13 @@ bool ValidateLimitations::withinLoopBody() const return !mLoopStack.empty(); } -bool ValidateLimitations::isLoopIndex(const TIntermSymbol* symbol) const +bool ValidateLimitations::isLoopIndex(TIntermSymbol *symbol) { - return IsLoopIndex(symbol, mLoopStack); + return mLoopStack.findLoop(symbol) != NULL; } -bool ValidateLimitations::validateLoopType(TIntermLoop* node) { +bool ValidateLimitations::validateLoopType(TIntermLoop *node) +{ TLoopType type = node->getType(); if (type == ELoopFor) return true; @@ -214,8 +146,7 @@ bool ValidateLimitations::validateLoopType(TIntermLoop* node) { return false; } -bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node, - TLoopInfo* info) +bool ValidateLimitations::validateForLoopHeader(TIntermLoop *node) { ASSERT(node->getType() == ELoopFor); @@ -223,74 +154,80 @@ bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node, // The for statement has the form: // for ( init-declaration ; condition ; expression ) statement // - if (!validateForLoopInit(node, info)) + int indexSymbolId = validateForLoopInit(node); + if (indexSymbolId < 0) return false; - if (!validateForLoopCond(node, info)) + if (!validateForLoopCond(node, indexSymbolId)) return false; - if (!validateForLoopExpr(node, info)) + if (!validateForLoopExpr(node, indexSymbolId)) return false; return true; } -bool ValidateLimitations::validateForLoopInit(TIntermLoop* node, - TLoopInfo* info) +int ValidateLimitations::validateForLoopInit(TIntermLoop *node) { - TIntermNode* init = node->getInit(); - if (init == NULL) { + TIntermNode *init = node->getInit(); + if (init == NULL) + { error(node->getLine(), "Missing init declaration", "for"); - return false; + return -1; } // // init-declaration has the form: // type-specifier identifier = constant-expression // - TIntermAggregate* decl = init->getAsAggregate(); - if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) { + TIntermAggregate *decl = init->getAsAggregate(); + if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) + { error(init->getLine(), "Invalid init declaration", "for"); - return false; + return -1; } // To keep things simple do not allow declaration list. - TIntermSequence& declSeq = decl->getSequence(); - if (declSeq.size() != 1) { + TIntermSequence &declSeq = decl->getSequence(); + if (declSeq.size() != 1) + { error(decl->getLine(), "Invalid init declaration", "for"); - return false; + return -1; } - TIntermBinary* declInit = declSeq[0]->getAsBinaryNode(); - if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) { + TIntermBinary *declInit = declSeq[0]->getAsBinaryNode(); + if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) + { error(decl->getLine(), "Invalid init declaration", "for"); - return false; + return -1; } - TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode(); - if (symbol == NULL) { + TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode(); + if (symbol == NULL) + { error(declInit->getLine(), "Invalid init declaration", "for"); - return false; + return -1; } // The loop index has type int or float. TBasicType type = symbol->getBasicType(); - if ((type != EbtInt) && (type != EbtFloat)) { + if ((type != EbtInt) && (type != EbtUInt) && (type != EbtFloat)) { error(symbol->getLine(), "Invalid type for loop index", getBasicString(type)); - return false; + return -1; } // The loop index is initialized with constant expression. - if (!isConstExpr(declInit->getRight())) { + if (!isConstExpr(declInit->getRight())) + { error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression", symbol->getSymbol().c_str()); - return false; + return -1; } - info->index.id = symbol->getId(); - return true; + return symbol->getId(); } -bool ValidateLimitations::validateForLoopCond(TIntermLoop* node, - TLoopInfo* info) +bool ValidateLimitations::validateForLoopCond(TIntermLoop *node, + int indexSymbolId) { - TIntermNode* cond = node->getCondition(); - if (cond == NULL) { + TIntermNode *cond = node->getCondition(); + if (cond == NULL) + { error(node->getLine(), "Missing condition", "for"); return false; } @@ -298,24 +235,28 @@ bool ValidateLimitations::validateForLoopCond(TIntermLoop* node, // condition has the form: // loop_index relational_operator constant_expression // - TIntermBinary* binOp = cond->getAsBinaryNode(); - if (binOp == NULL) { + TIntermBinary *binOp = cond->getAsBinaryNode(); + if (binOp == NULL) + { error(node->getLine(), "Invalid condition", "for"); return false; } // Loop index should be to the left of relational operator. - TIntermSymbol* symbol = binOp->getLeft()->getAsSymbolNode(); - if (symbol == NULL) { + TIntermSymbol *symbol = binOp->getLeft()->getAsSymbolNode(); + if (symbol == NULL) + { error(binOp->getLine(), "Invalid condition", "for"); return false; } - if (symbol->getId() != info->index.id) { + if (symbol->getId() != indexSymbolId) + { error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str()); return false; } // Relational operator is one of: > >= < <= == or !=. - switch (binOp->getOp()) { + switch (binOp->getOp()) + { case EOpEqual: case EOpNotEqual: case EOpLessThan: @@ -330,7 +271,8 @@ bool ValidateLimitations::validateForLoopCond(TIntermLoop* node, break; } // Loop index must be compared with a constant. - if (!isConstExpr(binOp->getRight())) { + if (!isConstExpr(binOp->getRight())) + { error(binOp->getLine(), "Loop index cannot be compared with non-constant expression", symbol->getSymbol().c_str()); @@ -340,11 +282,12 @@ bool ValidateLimitations::validateForLoopCond(TIntermLoop* node, return true; } -bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node, - TLoopInfo* info) +bool ValidateLimitations::validateForLoopExpr(TIntermLoop *node, + int indexSymbolId) { - TIntermNode* expr = node->getExpression(); - if (expr == NULL) { + TIntermNode *expr = node->getExpression(); + if (expr == NULL) + { error(node->getLine(), "Missing expression", "for"); return false; } @@ -358,50 +301,58 @@ bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node, // --loop_index // The last two forms are not specified in the spec, but I am assuming // its an oversight. - TIntermUnary* unOp = expr->getAsUnaryNode(); - TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode(); + TIntermUnary *unOp = expr->getAsUnaryNode(); + TIntermBinary *binOp = unOp ? NULL : expr->getAsBinaryNode(); TOperator op = EOpNull; - TIntermSymbol* symbol = NULL; - if (unOp != NULL) { + TIntermSymbol *symbol = NULL; + if (unOp != NULL) + { op = unOp->getOp(); symbol = unOp->getOperand()->getAsSymbolNode(); - } else if (binOp != NULL) { + } + else if (binOp != NULL) + { op = binOp->getOp(); symbol = binOp->getLeft()->getAsSymbolNode(); } // The operand must be loop index. - if (symbol == NULL) { + if (symbol == NULL) + { error(expr->getLine(), "Invalid expression", "for"); return false; } - if (symbol->getId() != info->index.id) { + if (symbol->getId() != indexSymbolId) + { error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str()); return false; } // The operator is one of: ++ -- += -=. - switch (op) { - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - ASSERT((unOp != NULL) && (binOp == NULL)); - break; - case EOpAddAssign: - case EOpSubAssign: - ASSERT((unOp == NULL) && (binOp != NULL)); - break; - default: - error(expr->getLine(), "Invalid operator", getOperatorString(op)); - return false; + switch (op) + { + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + ASSERT((unOp != NULL) && (binOp == NULL)); + break; + case EOpAddAssign: + case EOpSubAssign: + ASSERT((unOp == NULL) && (binOp != NULL)); + break; + default: + error(expr->getLine(), "Invalid operator", getOperatorString(op)); + return false; } // Loop index must be incremented/decremented with a constant. - if (binOp != NULL) { - if (!isConstExpr(binOp->getRight())) { + if (binOp != NULL) + { + if (!isConstExpr(binOp->getRight())) + { error(binOp->getLine(), "Loop index cannot be modified by non-constant expression", symbol->getSymbol().c_str()); @@ -412,7 +363,7 @@ bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node, return true; } -bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node) +bool ValidateLimitations::validateFunctionCall(TIntermAggregate *node) { ASSERT(node->getOp() == EOpFunctionCall); @@ -424,8 +375,9 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node) typedef std::vector<size_t> ParamIndex; ParamIndex pIndex; TIntermSequence& params = node->getSequence(); - for (TIntermSequence::size_type i = 0; i < params.size(); ++i) { - TIntermSymbol* symbol = params[i]->getAsSymbolNode(); + for (TIntermSequence::size_type i = 0; i < params.size(); ++i) + { + TIntermSymbol *symbol = params[i]->getAsSymbolNode(); if (symbol && isLoopIndex(symbol)) pIndex.push_back(i); } @@ -436,14 +388,16 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node) bool valid = true; TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable; - TSymbol* symbol = symbolTable.find(node->getName()); + TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->shaderVersion); ASSERT(symbol && symbol->isFunction()); - TFunction* function = static_cast<TFunction*>(symbol); + TFunction *function = static_cast<TFunction *>(symbol); for (ParamIndex::const_iterator i = pIndex.begin(); - i != pIndex.end(); ++i) { - const TParameter& param = function->getParam(*i); + i != pIndex.end(); ++i) + { + const TParameter ¶m = function->getParam(*i); TQualifier qual = param.type->getQualifier(); - if ((qual == EvqOut) || (qual == EvqInOut)) { + if ((qual == EvqOut) || (qual == EvqInOut)) + { error(params[*i]->getLine(), "Loop index cannot be used as argument to a function out or inout parameter", params[*i]->getAsSymbolNode()->getSymbol().c_str()); @@ -454,14 +408,16 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node) return valid; } -bool ValidateLimitations::validateOperation(TIntermOperator* node, - TIntermNode* operand) { +bool ValidateLimitations::validateOperation(TIntermOperator *node, + TIntermNode* operand) +{ // Check if loop index is modified in the loop body. if (!withinLoopBody() || !node->isAssignment()) return true; - const TIntermSymbol* symbol = operand->getAsSymbolNode(); - if (symbol && isLoopIndex(symbol)) { + TIntermSymbol *symbol = operand->getAsSymbolNode(); + if (symbol && isLoopIndex(symbol)) + { error(node->getLine(), "Loop index cannot be statically assigned to within the body of the loop", symbol->getSymbol().c_str()); @@ -469,13 +425,13 @@ bool ValidateLimitations::validateOperation(TIntermOperator* node, return true; } -bool ValidateLimitations::isConstExpr(TIntermNode* node) +bool ValidateLimitations::isConstExpr(TIntermNode *node) { ASSERT(node != NULL); return node->getAsConstantUnion() != NULL; } -bool ValidateLimitations::isConstIndexExpr(TIntermNode* node) +bool ValidateLimitations::isConstIndexExpr(TIntermNode *node) { ASSERT(node != NULL); @@ -484,15 +440,15 @@ bool ValidateLimitations::isConstIndexExpr(TIntermNode* node) return validate.isValid(); } -bool ValidateLimitations::validateIndexing(TIntermBinary* node) +bool ValidateLimitations::validateIndexing(TIntermBinary *node) { ASSERT((node->getOp() == EOpIndexDirect) || (node->getOp() == EOpIndexIndirect)); bool valid = true; - TIntermTyped* index = node->getRight(); + TIntermTyped *index = node->getRight(); // The index expression must have integral type. - if (!index->isScalar() || (index->getBasicType() != EbtInt)) { + if (!index->isScalarInt()) { error(index->getLine(), "Index expression must have integral type", index->getCompleteString().c_str()); @@ -500,10 +456,11 @@ bool ValidateLimitations::validateIndexing(TIntermBinary* node) } // The index expession must be a constant-index-expression unless // the operand is a uniform in a vertex shader. - TIntermTyped* operand = node->getLeft(); + TIntermTyped *operand = node->getLeft(); bool skip = (mShaderType == SH_VERTEX_SHADER) && (operand->getQualifier() == EvqUniform); - if (!skip && !isConstIndexExpr(index)) { + if (!skip && !isConstIndexExpr(index)) + { error(index->getLine(), "Index expression must be constant", "[]"); valid = false; } diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateLimitations.h b/chromium/third_party/angle/src/compiler/translator/ValidateLimitations.h new file mode 100644 index 00000000000..f28995c640b --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ValidateLimitations.h @@ -0,0 +1,55 @@ +// +// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/intermediate.h" +#include "compiler/translator/LoopInfo.h" + +class TInfoSinkBase; + +// Traverses intermediate tree to ensure that the shader does not exceed the +// minimum functionality mandated in GLSL 1.0 spec, Appendix A. +class ValidateLimitations : public TIntermTraverser +{ + public: + ValidateLimitations(ShShaderType shaderType, TInfoSinkBase &sink); + + int numErrors() const { return mNumErrors; } + + virtual bool visitBinary(Visit, TIntermBinary *); + virtual bool visitUnary(Visit, TIntermUnary *); + virtual bool visitAggregate(Visit, TIntermAggregate *); + virtual bool visitLoop(Visit, TIntermLoop *); + + private: + void error(TSourceLoc loc, const char *reason, const char *token); + + bool withinLoopBody() const; + bool isLoopIndex(TIntermSymbol *symbol); + bool validateLoopType(TIntermLoop *node); + + bool validateForLoopHeader(TIntermLoop *node); + // If valid, return the index symbol id; Otherwise, return -1. + int validateForLoopInit(TIntermLoop *node); + bool validateForLoopCond(TIntermLoop *node, int indexSymbolId); + bool validateForLoopExpr(TIntermLoop *node, int indexSymbolId); + + // Returns true if none of the loop indices is used as the argument to + // the given function out or inout parameter. + bool validateFunctionCall(TIntermAggregate *node); + bool validateOperation(TIntermOperator *node, TIntermNode *operand); + + // Returns true if indexing does not exceed the minimum functionality + // mandated in GLSL 1.0 spec, Appendix A, Section 5. + bool isConstExpr(TIntermNode *node); + bool isConstIndexExpr(TIntermNode *node); + bool validateIndexing(TIntermBinary *node); + + ShShaderType mShaderType; + TInfoSinkBase &mSink; + int mNumErrors; + TLoopStack mLoopStack; +}; + diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp new file mode 100644 index 00000000000..ac1c10d6b03 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp @@ -0,0 +1,78 @@ +// +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/ValidateOutputs.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/ParseContext.h" + +ValidateOutputs::ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers) + : mSink(sink), + mMaxDrawBuffers(maxDrawBuffers), + mNumErrors(0), + mHasUnspecifiedOutputLocation(false) +{ +} + +void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) +{ + TString name = symbol->getSymbol(); + TQualifier qualifier = symbol->getQualifier(); + + if (mVisitedSymbols.count(name) == 1) + return; + + mVisitedSymbols.insert(name); + + if (qualifier == EvqFragmentOut) + { + const TType &type = symbol->getType(); + const int location = type.getLayoutQualifier().location; + + if (mHasUnspecifiedOutputLocation) + { + error(symbol->getLine(), "must explicitly specify all locations when using multiple fragment outputs", name.c_str()); + } + else if (location == -1) + { + mHasUnspecifiedOutputLocation = true; + } + else + { + OutputMap::iterator mapEntry = mOutputMap.find(location); + if (mapEntry == mOutputMap.end()) + { + const int elementCount = type.isArray() ? type.getArraySize() : 1; + if (location + elementCount > mMaxDrawBuffers) + { + error(symbol->getLine(), "output location must be < MAX_DRAW_BUFFERS", name.c_str()); + } + + for (int elementIndex = 0; elementIndex < elementCount; elementIndex++) + { + const int offsetLocation = location + elementIndex; + mOutputMap[offsetLocation] = symbol; + } + } + else + { + std::stringstream strstr; + strstr << "conflicting output locations with previously defined output '" + << mapEntry->second->getSymbol() << "'"; + + error(symbol->getLine(), strstr.str().c_str(), name.c_str()); + } + } + } +} + +void ValidateOutputs::error(TSourceLoc loc, const char *reason, const char* token) +{ + mSink.prefix(EPrefixError); + mSink.location(loc); + mSink << "'" << token << "' : " << reason << "\n"; + mNumErrors++; +} diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.h b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.h new file mode 100644 index 00000000000..e391ad94860 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.h @@ -0,0 +1,33 @@ +// +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/intermediate.h" + +#include <set> + +class TInfoSinkBase; + +class ValidateOutputs : public TIntermTraverser +{ + public: + ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers); + + int numErrors() const { return mNumErrors; } + + virtual void visitSymbol(TIntermSymbol*); + + private: + TInfoSinkBase& mSink; + int mMaxDrawBuffers; + int mNumErrors; + bool mHasUnspecifiedOutputLocation; + + typedef std::map<int, TIntermSymbol*> OutputMap; + OutputMap mOutputMap; + std::set<TString> mVisitedSymbols; + + void error(TSourceLoc loc, const char *reason, const char* token); +}; diff --git a/chromium/third_party/angle/src/compiler/VariableInfo.cpp b/chromium/third_party/angle/src/compiler/translator/VariableInfo.cpp index f3f7b1ef35a..d0b19907f4c 100644 --- a/chromium/third_party/angle/src/compiler/VariableInfo.cpp +++ b/chromium/third_party/angle/src/compiler/translator/VariableInfo.cpp @@ -1,10 +1,10 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/VariableInfo.h" +#include "compiler/translator/VariableInfo.h" namespace { @@ -21,11 +21,32 @@ ShDataType getVariableDataType(const TType& type) switch (type.getBasicType()) { case EbtFloat: if (type.isMatrix()) { - switch (type.getNominalSize()) { - case 2: return SH_FLOAT_MAT2; - case 3: return SH_FLOAT_MAT3; - case 4: return SH_FLOAT_MAT4; - default: UNREACHABLE(); + switch (type.getCols()) + { + case 2: + switch (type.getRows()) + { + case 2: return SH_FLOAT_MAT2; + case 3: return SH_FLOAT_MAT2x3; + case 4: return SH_FLOAT_MAT2x4; + default: UNREACHABLE(); + } + case 3: + switch (type.getRows()) + { + case 2: return SH_FLOAT_MAT3x2; + case 3: return SH_FLOAT_MAT3; + case 4: return SH_FLOAT_MAT3x4; + default: UNREACHABLE(); + } + case 4: + switch (type.getRows()) + { + case 2: return SH_FLOAT_MAT4x2; + case 3: return SH_FLOAT_MAT4x3; + case 4: return SH_FLOAT_MAT4; + default: UNREACHABLE(); + } } } else if (type.isVector()) { switch (type.getNominalSize()) { @@ -50,6 +71,19 @@ ShDataType getVariableDataType(const TType& type) } else { return SH_INT; } + case EbtUInt: + if (type.isMatrix()) { + UNREACHABLE(); + } else if (type.isVector()) { + switch (type.getNominalSize()) { + case 2: return SH_UNSIGNED_INT_VEC2; + case 3: return SH_UNSIGNED_INT_VEC3; + case 4: return SH_UNSIGNED_INT_VEC4; + default: UNREACHABLE(); + } + } else { + return SH_UNSIGNED_INT; + } case EbtBool: if (type.isMatrix()) { UNREACHABLE(); @@ -64,9 +98,22 @@ ShDataType getVariableDataType(const TType& type) return SH_BOOL; } case EbtSampler2D: return SH_SAMPLER_2D; + case EbtSampler3D: return SH_SAMPLER_3D; case EbtSamplerCube: return SH_SAMPLER_CUBE; case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES; case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB; + case EbtSampler2DArray: return SH_SAMPLER_2D_ARRAY; + case EbtISampler2D: return SH_INT_SAMPLER_2D; + case EbtISampler3D: return SH_INT_SAMPLER_3D; + case EbtISamplerCube: return SH_INT_SAMPLER_CUBE; + case EbtISampler2DArray: return SH_INT_SAMPLER_2D_ARRAY; + case EbtUSampler2D: return SH_UNSIGNED_INT_SAMPLER_2D; + case EbtUSampler3D: return SH_UNSIGNED_INT_SAMPLER_3D; + case EbtUSamplerCube: return SH_UNSIGNED_INT_SAMPLER_CUBE; + case EbtUSampler2DArray: return SH_UNSIGNED_INT_SAMPLER_2D_ARRAY; + case EbtSampler2DShadow: return SH_SAMPLER_2D_SHADOW; + case EbtSamplerCubeShadow: return SH_SAMPLER_CUBE_SHADOW; + case EbtSampler2DArrayShadow: return SH_SAMPLER_2D_ARRAY_SHADOW; default: UNREACHABLE(); } return SH_NONE; @@ -89,7 +136,7 @@ void getVariableInfo(const TType& type, TVariableInfoList& infoList, ShHashFunction64 hashFunction) { - if (type.getBasicType() == EbtStruct) { + if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) { if (type.isArray()) { for (int i = 0; i < type.getArraySize(); ++i) { TString lname = name + arrayBrackets(i); @@ -116,10 +163,12 @@ void getBuiltInVariableInfo(const TType& type, varInfo.name = (name + "[0]").c_str(); varInfo.mappedName = (mappedName + "[0]").c_str(); varInfo.size = type.getArraySize(); + varInfo.isArray = true; } else { varInfo.name = name.c_str(); varInfo.mappedName = mappedName.c_str(); varInfo.size = 1; + varInfo.isArray = false; } varInfo.precision = type.getPrecision(); varInfo.type = getVariableDataType(type); @@ -132,9 +181,11 @@ void getUserDefinedVariableInfo(const TType& type, TVariableInfoList& infoList, ShHashFunction64 hashFunction) { - ASSERT(type.getBasicType() == EbtStruct); + ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock()); - const TFieldList& fields = type.getStruct()->fields(); + const TFieldList& fields = type.isInterfaceBlock() ? + type.getInterfaceBlock()->fields() : + type.getStruct()->fields(); for (size_t i = 0; i < fields.size(); ++i) { const TType& fieldType = *(fields[i]->type()); const TString& fieldName = fields[i]->name(); @@ -167,6 +218,7 @@ TVariableInfo* findVariable(const TType& type, TVariableInfo::TVariableInfo() : type(SH_NONE), size(0), + isArray(false), precision(EbpUndefined), staticUse(false) { @@ -175,6 +227,7 @@ TVariableInfo::TVariableInfo() TVariableInfo::TVariableInfo(ShDataType type, int size) : type(type), size(size), + isArray(false), precision(EbpUndefined), staticUse(false) { @@ -269,12 +322,26 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node) case EOpDeclaration: { const TIntermSequence& sequence = node->getSequence(); TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier(); - if (qualifier == EvqAttribute || qualifier == EvqUniform || + if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqUniform || qualifier == EvqVaryingIn || qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut) { - TVariableInfoList& infoList = qualifier == EvqAttribute ? mAttribs : - (qualifier == EvqUniform ? mUniforms : mVaryings); + TVariableInfoList *infoList = NULL; + + switch (qualifier) + { + case EvqAttribute: + case EvqVertexIn: + infoList = &mAttribs; + break; + case EvqUniform: + infoList = &mUniforms; + break; + default: + infoList = &mVaryings; + break; + } + for (TIntermSequence::const_iterator i = sequence.begin(); i != sequence.end(); ++i) { @@ -289,11 +356,11 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node) if (mHashFunction == NULL) processedSymbol = variable->getSymbol(); else - processedSymbol = TIntermTraverser::hash(variable->getOriginalSymbol(), mHashFunction); + processedSymbol = TIntermTraverser::hash(variable->getSymbol(), mHashFunction); getVariableInfo(variable->getType(), - variable->getOriginalSymbol(), + variable->getSymbol(), processedSymbol, - infoList, + *infoList, mHashFunction); visitChildren = false; } @@ -305,4 +372,3 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node) return visitChildren; } - diff --git a/chromium/third_party/angle/src/compiler/VariableInfo.h b/chromium/third_party/angle/src/compiler/translator/VariableInfo.h index 3c7f2a5f84f..fc9e15301bc 100644 --- a/chromium/third_party/angle/src/compiler/VariableInfo.h +++ b/chromium/third_party/angle/src/compiler/translator/VariableInfo.h @@ -7,8 +7,7 @@ #ifndef COMPILER_VARIABLE_INFO_H_ #define COMPILER_VARIABLE_INFO_H_ -#include "GLSLANG/ShaderLang.h" -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" // Provides information about a variable. // It is currently being used to store info about active attribs and uniforms. @@ -20,6 +19,7 @@ struct TVariableInfo { TPersistString mappedName; ShDataType type; int size; + bool isArray; TPrecision precision; bool staticUse; }; diff --git a/chromium/third_party/angle/src/compiler/VariablePacker.cpp b/chromium/third_party/angle/src/compiler/translator/VariablePacker.cpp index 89572877635..6390e303941 100644 --- a/chromium/third_party/angle/src/compiler/VariablePacker.cpp +++ b/chromium/third_party/angle/src/compiler/translator/VariablePacker.cpp @@ -3,16 +3,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/VariablePacker.h" +#include "compiler/translator/VariablePacker.h" #include <algorithm> -#include "compiler/ShHandle.h" +#include "compiler/translator/ShHandle.h" namespace { int GetSortOrder(ShDataType type) { switch (type) { case SH_FLOAT_MAT4: + case SH_FLOAT_MAT2x4: + case SH_FLOAT_MAT3x4: + case SH_FLOAT_MAT4x2: + case SH_FLOAT_MAT4x3: return 0; case SH_FLOAT_MAT2: return 1; @@ -21,6 +25,8 @@ int GetSortOrder(ShDataType type) case SH_BOOL_VEC4: return 2; case SH_FLOAT_MAT3: + case SH_FLOAT_MAT2x3: + case SH_FLOAT_MAT3x2: return 3; case SH_FLOAT_VEC3: case SH_INT_VEC3: @@ -50,11 +56,17 @@ int VariablePacker::GetNumComponentsPerRow(ShDataType type) switch (type) { case SH_FLOAT_MAT4: case SH_FLOAT_MAT2: + case SH_FLOAT_MAT2x4: + case SH_FLOAT_MAT3x4: + case SH_FLOAT_MAT4x2: + case SH_FLOAT_MAT4x3: case SH_FLOAT_VEC4: case SH_INT_VEC4: case SH_BOOL_VEC4: return 4; case SH_FLOAT_MAT3: + case SH_FLOAT_MAT2x3: + case SH_FLOAT_MAT3x2: case SH_FLOAT_VEC3: case SH_INT_VEC3: case SH_BOOL_VEC3: @@ -81,8 +93,14 @@ int VariablePacker::GetNumRows(ShDataType type) { switch (type) { case SH_FLOAT_MAT4: + case SH_FLOAT_MAT2x4: + case SH_FLOAT_MAT3x4: + case SH_FLOAT_MAT4x3: + case SH_FLOAT_MAT4x2: return 4; case SH_FLOAT_MAT3: + case SH_FLOAT_MAT2x3: + case SH_FLOAT_MAT3x2: return 3; case SH_FLOAT_MAT2: return 2; @@ -197,6 +215,14 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVa bottomNonFullRow_ = maxRows_ - 1; TVariableInfoList variables(in_variables); + // Check whether each variable fits in the available vectors. + for (size_t i = 0; i < variables.size(); i++) { + const TVariableInfo& variable = variables[i]; + if (variable.size > maxVectors / GetNumRows(variable.type)) { + return false; + } + } + // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific // order by type, then by size of array, largest first. std::sort(variables.begin(), variables.end(), TVariableInfoComparer()); diff --git a/chromium/third_party/angle/src/compiler/VariablePacker.h b/chromium/third_party/angle/src/compiler/translator/VariablePacker.h index 8987066cc37..fd6090827cd 100644 --- a/chromium/third_party/angle/src/compiler/VariablePacker.h +++ b/chromium/third_party/angle/src/compiler/translator/VariablePacker.h @@ -8,7 +8,7 @@ #define _VARIABLEPACKER_INCLUDED_ #include <vector> -#include "compiler/ShHandle.h" +#include "compiler/translator/ShHandle.h" class VariablePacker { public: diff --git a/chromium/third_party/angle/src/compiler/VersionGLSL.cpp b/chromium/third_party/angle/src/compiler/translator/VersionGLSL.cpp index 7a82bb4dc17..dd11f99eb89 100644 --- a/chromium/third_party/angle/src/compiler/VersionGLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/VersionGLSL.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/VersionGLSL.h" +#include "compiler/translator/VersionGLSL.h" static const int GLSL_VERSION_110 = 110; static const int GLSL_VERSION_120 = 120; diff --git a/chromium/third_party/angle/src/compiler/VersionGLSL.h b/chromium/third_party/angle/src/compiler/translator/VersionGLSL.h index 1c1cb1ab97b..8a401c4e92b 100644 --- a/chromium/third_party/angle/src/compiler/VersionGLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/VersionGLSL.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,8 +7,7 @@ #ifndef COMPILER_VERSIONGLSL_H_ #define COMPILER_VERSIONGLSL_H_ -#include "GLSLANG/ShaderLang.h" -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" // Traverses the intermediate tree to return the minimum GLSL version // required to legally access all built-in features used in the shader. @@ -24,6 +23,7 @@ // - matrix constructors taking matrix as argument. // - array as "out" function parameters // +// TODO: ES3 equivalent versions of GLSL class TVersionGLSL : public TIntermTraverser { public: TVersionGLSL(ShShaderType type); diff --git a/chromium/third_party/angle/src/compiler/debug.cpp b/chromium/third_party/angle/src/compiler/translator/compilerdebug.cpp index 6a7b0425127..10cbe43b8d5 100644 --- a/chromium/third_party/angle/src/compiler/debug.cpp +++ b/chromium/third_party/angle/src/compiler/translator/compilerdebug.cpp @@ -6,17 +6,17 @@ // debug.cpp: Debugging utilities. -#include "compiler/debug.h" +#include "compiler/translator/compilerdebug.h" #include <stdarg.h> #include <stdio.h> -#include "compiler/InitializeParseContext.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/ParseContext.h" +#ifdef TRACE_ENABLED static const int kTraceBufferLen = 1024; -#ifdef TRACE_ENABLED extern "C" { void Trace(const char *format, ...) { if (!format) return; diff --git a/chromium/third_party/angle/src/compiler/debug.h b/chromium/third_party/angle/src/compiler/translator/compilerdebug.h index 7a371516af0..7a371516af0 100644 --- a/chromium/third_party/angle/src/compiler/debug.h +++ b/chromium/third_party/angle/src/compiler/translator/compilerdebug.h diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraph.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp index ca661d67678..19ddf5c4392 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraph.cpp +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp @@ -6,8 +6,8 @@ #pragma warning(disable: 4718) -#include "compiler/depgraph/DependencyGraph.h" -#include "compiler/depgraph/DependencyGraphBuilder.h" +#include "compiler/translator/depgraph/DependencyGraph.h" +#include "compiler/translator/depgraph/DependencyGraphBuilder.h" TDependencyGraph::TDependencyGraph(TIntermNode* intermNode) { diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraph.h b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.h index 5a9c35d00b7..5ea1cbb837d 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraph.h +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.h @@ -7,7 +7,7 @@ #ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H #define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H -#include "compiler/intermediate.h" +#include "compiler/translator/intermediate.h" #include <set> #include <stack> diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphBuilder.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp index 026e6d57a4f..d5f2cba5fc0 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphBuilder.cpp +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/depgraph/DependencyGraphBuilder.h" +#include "compiler/translator/depgraph/DependencyGraphBuilder.h" void TDependencyGraphBuilder::build(TIntermNode* node, TDependencyGraph* graph) { diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphBuilder.h b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h index c5f232cb21e..3e928fb77eb 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphBuilder.h +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h @@ -7,7 +7,7 @@ #ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H #define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H -#include "compiler/depgraph/DependencyGraph.h" +#include "compiler/translator/depgraph/DependencyGraph.h" // // Creates a dependency graph of symbols, function calls, conditions etc. by traversing a diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphOutput.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp index 6fc489e7b6f..e226333545f 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphOutput.cpp +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/depgraph/DependencyGraphOutput.h" +#include "compiler/translator/depgraph/DependencyGraphOutput.h" void TDependencyGraphOutput::outputIndentation() { diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphOutput.h b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h index 01447da987d..c3a4112278f 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphOutput.h +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h @@ -7,8 +7,8 @@ #ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H #define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H -#include "compiler/depgraph/DependencyGraph.h" -#include "compiler/InfoSink.h" +#include "compiler/translator/depgraph/DependencyGraph.h" +#include "compiler/translator/InfoSink.h" class TDependencyGraphOutput : public TDependencyGraphTraverser { public: diff --git a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphTraverse.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp index b158575cec3..197fde97e26 100644 --- a/chromium/third_party/angle/src/compiler/depgraph/DependencyGraphTraverse.cpp +++ b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/depgraph/DependencyGraph.h" +#include "compiler/translator/depgraph/DependencyGraph.h" // These methods do a breadth-first traversal through the graph and mark visited nodes. diff --git a/chromium/third_party/angle/src/compiler/generate_parser.sh b/chromium/third_party/angle/src/compiler/translator/generate_parser.sh index e4d88b2e84c..e4d88b2e84c 100755..100644 --- a/chromium/third_party/angle/src/compiler/generate_parser.sh +++ b/chromium/third_party/angle/src/compiler/translator/generate_parser.sh diff --git a/chromium/third_party/angle/src/compiler/glslang.h b/chromium/third_party/angle/src/compiler/translator/glslang.h index f221199093c..f221199093c 100644 --- a/chromium/third_party/angle/src/compiler/glslang.h +++ b/chromium/third_party/angle/src/compiler/translator/glslang.h diff --git a/chromium/third_party/angle/src/compiler/translator/glslang.l b/chromium/third_party/angle/src/compiler/translator/glslang.l new file mode 100644 index 00000000000..518b78df11e --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/glslang.l @@ -0,0 +1,558 @@ +/* +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Lex specification for GLSL ES. +Based on ANSI C grammar, Lex specification: +http://www.lysator.liu.se/c/ANSI-C-grammar-l.html + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, +WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). +*/ + +%top{ +// +// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +// Ignore errors in auto-generated code. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wswitch-enum" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065) +#pragma warning(disable: 4189) +#pragma warning(disable: 4505) +#pragma warning(disable: 4701) +#endif +} + +%{ +#include "compiler/translator/glslang.h" +#include "compiler/translator/ParseContext.h" +#include "compiler/preprocessor/Token.h" +#include "compiler/translator/util.h" +#include "compiler/translator/length_limits.h" +#include "glslang_tab.h" + +/* windows only pragma */ +#ifdef _MSC_VER +#pragma warning(disable : 4102) +#endif + +#define YY_USER_ACTION \ + yylloc->first_file = yylloc->last_file = yycolumn; \ + yylloc->first_line = yylloc->last_line = yylineno; + +#define YY_INPUT(buf, result, max_size) \ + result = string_input(buf, max_size, yyscanner); + +static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner); +static int check_type(yyscan_t yyscanner); +static int reserved_word(yyscan_t yyscanner); +static int ES2_reserved_ES3_keyword(TParseContext *context, int token); +static int ES2_keyword_ES3_reserved(TParseContext *context, int token); +static int ES2_ident_ES3_keyword(TParseContext *context, int token); +static int uint_constant(TParseContext *context); +static int int_constant(yyscan_t yyscanner); +static int float_constant(yyscan_t yyscanner); +static int floatsuffix_check(TParseContext* context); +%} + +%option noyywrap nounput never-interactive +%option yylineno reentrant bison-bridge bison-locations +%option extra-type="TParseContext*" + +D [0-9] +L [a-zA-Z_] +H [a-fA-F0-9] +E [Ee][+-]?{D}+ +O [0-7] + +%% + +%{ + TParseContext* context = yyextra; +%} + +"invariant" { return INVARIANT; } +"highp" { return HIGH_PRECISION; } +"mediump" { return MEDIUM_PRECISION; } +"lowp" { return LOW_PRECISION; } +"precision" { return PRECISION; } + +"attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); } +"const" { return CONST_QUAL; } +"uniform" { return UNIFORM; } +"varying" { return ES2_keyword_ES3_reserved(context, VARYING); } + +"break" { return BREAK; } +"continue" { return CONTINUE; } +"do" { return DO; } +"for" { return FOR; } +"while" { return WHILE; } + +"if" { return IF; } +"else" { return ELSE; } +"switch" { return ES2_reserved_ES3_keyword(context, SWITCH); } +"case" { return ES2_ident_ES3_keyword(context, CASE); } +"default" { return ES2_reserved_ES3_keyword(context, DEFAULT); } + +"centroid" { return ES2_ident_ES3_keyword(context, CENTROID); } +"flat" { return ES2_reserved_ES3_keyword(context, FLAT); } +"smooth" { return ES2_ident_ES3_keyword(context, SMOOTH); } + +"in" { return IN_QUAL; } +"out" { return OUT_QUAL; } +"inout" { return INOUT_QUAL; } + +"float" { return FLOAT_TYPE; } +"int" { return INT_TYPE; } +"uint" { return ES2_ident_ES3_keyword(context, UINT_TYPE); } +"void" { return VOID_TYPE; } +"bool" { return BOOL_TYPE; } +"true" { yylval->lex.b = true; return BOOLCONSTANT; } +"false" { yylval->lex.b = false; return BOOLCONSTANT; } + +"discard" { return DISCARD; } +"return" { return RETURN; } + +"mat2" { return MATRIX2; } +"mat3" { return MATRIX3; } +"mat4" { return MATRIX4; } + +"mat2x2" { return ES2_ident_ES3_keyword(context, MATRIX2); } +"mat3x3" { return ES2_ident_ES3_keyword(context, MATRIX3); } +"mat4x4" { return ES2_ident_ES3_keyword(context, MATRIX4); } + +"mat2x3" { return ES2_ident_ES3_keyword(context, MATRIX2x3); } +"mat3x2" { return ES2_ident_ES3_keyword(context, MATRIX3x2); } +"mat2x4" { return ES2_ident_ES3_keyword(context, MATRIX2x4); } +"mat4x2" { return ES2_ident_ES3_keyword(context, MATRIX4x2); } +"mat3x4" { return ES2_ident_ES3_keyword(context, MATRIX3x4); } +"mat4x3" { return ES2_ident_ES3_keyword(context, MATRIX4x3); } + +"vec2" { return VEC2; } +"vec3" { return VEC3; } +"vec4" { return VEC4; } +"ivec2" { return IVEC2; } +"ivec3" { return IVEC3; } +"ivec4" { return IVEC4; } +"bvec2" { return BVEC2; } +"bvec3" { return BVEC3; } +"bvec4" { return BVEC4; } +"uvec2" { return ES2_ident_ES3_keyword(context, UVEC2); } +"uvec3" { return ES2_ident_ES3_keyword(context, UVEC3); } +"uvec4" { return ES2_ident_ES3_keyword(context, UVEC4); } + +"sampler2D" { return SAMPLER2D; } +"samplerCube" { return SAMPLERCUBE; } +"samplerExternalOES" { return SAMPLER_EXTERNAL_OES; } +"sampler3D" { return ES2_reserved_ES3_keyword(context, SAMPLER3D); } +"sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); } +"sampler2DRect" { return SAMPLER2DRECT; } +"sampler2DArray" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAY); } +"isampler2D" { return ES2_ident_ES3_keyword(context, ISAMPLER2D); } +"isampler3D" { return ES2_ident_ES3_keyword(context, ISAMPLER3D); } +"isamplerCube" { return ES2_ident_ES3_keyword(context, ISAMPLERCUBE); } +"isampler2DArray" { return ES2_ident_ES3_keyword(context, ISAMPLER2DARRAY); } +"usampler2D" { return ES2_ident_ES3_keyword(context, USAMPLER2D); } +"usampler3D" { return ES2_ident_ES3_keyword(context, USAMPLER3D); } +"usamplerCube" { return ES2_ident_ES3_keyword(context, USAMPLERCUBE); } +"usampler2DArray" { return ES2_ident_ES3_keyword(context, USAMPLER2DARRAY); } +"sampler2DShadow" { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); } +"samplerCubeShadow" { return ES2_ident_ES3_keyword(context, SAMPLERCUBESHADOW); } +"sampler2DArrayShadow" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAYSHADOW); } + +"struct" { return STRUCT; } + +"layout" { return ES2_ident_ES3_keyword(context, LAYOUT); } + + /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */ +"coherent" | +"restrict" | +"readonly" | +"writeonly" | +"resource" | +"atomic_uint" | +"noperspective" | +"patch" | +"sample" | +"subroutine" | +"common" | +"partition" | +"active" | + +"filter" | +"image1D" | +"image2D" | +"image3D" | +"imageCube" | +"iimage1D" | +"iimage2D" | +"iimage3D" | +"iimageCube" | +"uimage1D" | +"uimage2D" | +"uimage3D" | +"uimageCube" | +"image1DArray" | +"image2DArray" | +"iimage1DArray" | +"iimage2DArray" | +"uimage1DArray" | +"uimage2DArray" | +"image1DShadow" | +"image2DShadow" | +"image1DArrayShadow" | +"image2DArrayShadow" | +"imageBuffer" | +"iimageBuffer" | +"uimageBuffer" | + +"sampler1DArray" | +"sampler1DArrayShadow" | +"isampler1D" | +"isampler1DArray" | +"usampler1D" | +"usampler1DArray" | +"isampler2DRect" | +"usampler2DRect" | +"samplerBuffer" | +"isamplerBuffer" | +"usamplerBuffer" | +"sampler2DMS" | +"isampler2DMS" | +"usampler2DMS" | +"sampler2DMSArray" | +"isampler2DMSArray" | +"usampler2DMSArray" { + if (context->shaderVersion < 300) { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + return reserved_word(yyscanner); +} + + /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */ +"packed" { + if (context->shaderVersion >= 300) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + + return reserved_word(yyscanner); +} + + /* Reserved keywords */ +"asm" | + +"class" | +"union" | +"enum" | +"typedef" | +"template" | +"this" | + +"goto" | + +"inline" | +"noinline" | +"volatile" | +"public" | +"static" | +"extern" | +"external" | +"interface" | + +"long" | +"short" | +"double" | +"half" | +"fixed" | +"unsigned" | +"superp" | + +"input" | +"output" | + +"hvec2" | +"hvec3" | +"hvec4" | +"dvec2" | +"dvec3" | +"dvec4" | +"fvec2" | +"fvec3" | +"fvec4" | + +"sampler1D" | +"sampler1DShadow" | +"sampler2DRectShadow" | + +"sizeof" | +"cast" | + +"namespace" | +"using" { return reserved_word(yyscanner); } + +{L}({L}|{D})* { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); +} + +0[xX]{H}+ { return int_constant(yyscanner); } +0{O}+ { return int_constant(yyscanner); } +{D}+ { return int_constant(yyscanner); } + +0[xX]{H}+[uU] { return uint_constant(context); } +0{O}+[uU] { return uint_constant(context); } +{D}+[uU] { return uint_constant(context); } + +{D}+{E} { return float_constant(yyscanner); } +{D}+"."{D}*({E})? { return float_constant(yyscanner); } +"."{D}+({E})? { return float_constant(yyscanner); } + +{D}+{E}[fF] { return floatsuffix_check(context); } +{D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); } +"."{D}+({E})?[fF] { return floatsuffix_check(context); } + +"+=" { return ADD_ASSIGN; } +"-=" { return SUB_ASSIGN; } +"*=" { return MUL_ASSIGN; } +"/=" { return DIV_ASSIGN; } +"%=" { return MOD_ASSIGN; } +"<<=" { return LEFT_ASSIGN; } +">>=" { return RIGHT_ASSIGN; } +"&=" { return AND_ASSIGN; } +"^=" { return XOR_ASSIGN; } +"|=" { return OR_ASSIGN; } + +"++" { return INC_OP; } +"--" { return DEC_OP; } +"&&" { return AND_OP; } +"||" { return OR_OP; } +"^^" { return XOR_OP; } +"<=" { return LE_OP; } +">=" { return GE_OP; } +"==" { return EQ_OP; } +"!=" { return NE_OP; } +"<<" { return LEFT_OP; } +">>" { return RIGHT_OP; } +";" { return SEMICOLON; } +("{"|"<%") { return LEFT_BRACE; } +("}"|"%>") { return RIGHT_BRACE; } +"," { return COMMA; } +":" { return COLON; } +"=" { return EQUAL; } +"(" { return LEFT_PAREN; } +")" { return RIGHT_PAREN; } +("["|"<:") { return LEFT_BRACKET; } +("]"|":>") { return RIGHT_BRACKET; } +"." { return DOT; } +"!" { return BANG; } +"-" { return DASH; } +"~" { return TILDE; } +"+" { return PLUS; } +"*" { return STAR; } +"/" { return SLASH; } +"%" { return PERCENT; } +"<" { return LEFT_ANGLE; } +">" { return RIGHT_ANGLE; } +"|" { return VERTICAL_BAR; } +"^" { return CARET; } +"&" { return AMPERSAND; } +"?" { return QUESTION; } + +[ \t\v\n\f\r] { } +<<EOF>> { yyterminate(); } +. { assert(false); return 0; } + +%% + +yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { + pp::Token token; + yyget_extra(yyscanner)->preprocessor.lex(&token); + yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); + if (len < max_size) + memcpy(buf, token.text.c_str(), len); + yyset_column(token.location.file, yyscanner); + yyset_lineno(token.location.line, yyscanner); + + if (len >= max_size) + YY_FATAL_ERROR("Input buffer overflow"); + else if (len > 0) + buf[len++] = ' '; + return len; +} + +int check_type(yyscan_t yyscanner) { + struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; + + int token = IDENTIFIER; + TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion); + if (symbol && symbol->isVariable()) { + TVariable* variable = static_cast<TVariable*>(symbol); + if (variable->isUserType()) { + token = TYPE_NAME; + } + } + yylval->lex.symbol = symbol; + return token; +} + +int reserved_word(yyscan_t yyscanner) { + struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; + + yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); + yyextra->recover(); + return 0; +} + +int ES2_reserved_ES3_keyword(TParseContext *context, int token) +{ + yyscan_t yyscanner = (yyscan_t) context->scanner; + + if (context->shaderVersion < 300) + { + return reserved_word(yyscanner); + } + + return token; +} + +int ES2_keyword_ES3_reserved(TParseContext *context, int token) +{ + yyscan_t yyscanner = (yyscan_t) context->scanner; + + if (context->shaderVersion >= 300) + { + return reserved_word(yyscanner); + } + + return token; +} + +int ES2_ident_ES3_keyword(TParseContext *context, int token) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->scanner; + + // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name + if (context->shaderVersion < 300) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + + return token; +} + +int uint_constant(TParseContext *context) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->scanner; + + if (context->shaderVersion < 300) + { + context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); + context->recover(); + return 0; + } + + if (!atoi_clamp(yytext, &(yylval->lex.i))) + yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + + return UINTCONSTANT; +} + +int floatsuffix_check(TParseContext* context) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + + if (context->shaderVersion < 300) + { + context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); + context->recover(); + return 0; + } + + if (!atof_clamp(yytext, &(yylval->lex.f))) + yyextra->warning(*yylloc, "Float overflow", yytext, ""); + + return(FLOATCONSTANT); +} + +void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) { + context->error(*lloc, reason, yyget_text(context->scanner)); + context->recover(); +} + +int int_constant(yyscan_t yyscanner) { + struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; + + if (!atoi_clamp(yytext, &(yylval->lex.i))) + yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + return INTCONSTANT; +} + +int float_constant(yyscan_t yyscanner) { + struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; + + if (!atof_clamp(yytext, &(yylval->lex.f))) + yyextra->warning(*yylloc, "Float overflow", yytext, ""); + return FLOATCONSTANT; +} + +int glslang_initialize(TParseContext* context) { + yyscan_t scanner = NULL; + if (yylex_init_extra(context, &scanner)) + return 1; + + context->scanner = scanner; + return 0; +} + +int glslang_finalize(TParseContext* context) { + yyscan_t scanner = context->scanner; + if (scanner == NULL) return 0; + + context->scanner = NULL; + yylex_destroy(scanner); + + return 0; +} + +int glslang_scan(size_t count, const char* const string[], const int length[], + TParseContext* context) { + yyrestart(NULL, context->scanner); + yyset_column(0, context->scanner); + yyset_lineno(1, context->scanner); + + // Initialize preprocessor. + if (!context->preprocessor.init(count, string, length)) + return 1; + + // Define extension macros. + const TExtensionBehavior& extBehavior = context->extensionBehavior(); + for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); + iter != extBehavior.end(); ++iter) { + context->preprocessor.predefineMacro(iter->first.c_str(), 1); + } + if (context->fragmentPrecisionHigh) + context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); + + context->preprocessor.setMaxTokenSize(GetGlobalMaxTokenSize(context->shaderSpec)); + + return 0; +} + diff --git a/chromium/third_party/angle/src/compiler/glslang.y b/chromium/third_party/angle/src/compiler/translator/glslang.y index a8dceb40acb..8ebf2d1f641 100644 --- a/chromium/third_party/angle/src/compiler/glslang.y +++ b/chromium/third_party/angle/src/compiler/translator/glslang.y @@ -1,6 +1,6 @@ /* // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -15,7 +15,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). %{ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -34,15 +34,15 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #pragma warning(disable: 4701) #endif -#include "compiler/SymbolTable.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/ParseContext.h" #include "GLSLANG/ShaderLang.h" #define YYENABLE_NLS 0 #define YYLEX_PARAM context->scanner -%} +%} %expect 1 /* One shift reduce conflict because of if | else */ %pure-parser %parse-param {TParseContext* context} @@ -51,7 +51,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). %code requires { #define YYLTYPE TSourceLoc #define YYLTYPE_IS_DECLARED 1 -#define SH_MAX_TOKEN_LENGTH 256 // WebGL spec. } %union { @@ -60,6 +59,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). TString *string; float f; int i; + unsigned int u; bool b; }; TSymbol* symbol; @@ -75,6 +75,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). union { TPublicType type; TPrecision precision; + TLayoutQualifier layoutQualifier; TQualifier qualifier; TFunction* function; TParameter param; @@ -117,17 +118,38 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) context->recover(); \ } \ } + +#define ES2_ONLY(S, L) { \ + if (context->shaderVersion != 100) { \ + context->error(L, " supported in GLSL ES 1.00 only ", S); \ + context->recover(); \ + } \ +} + +#define ES3_ONLY(TOKEN, LINE, REASON) { \ + if (context->shaderVersion != 300) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ + context->recover(); \ + } \ +} %} %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION -%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE -%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN -%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 +%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE +%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING +%token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3 +%token <lex> CENTROID FLAT SMOOTH %token <lex> STRUCT VOID_TYPE WHILE -%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT - -%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT +%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY +%token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY +%token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY +%token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW +%token <lex> LAYOUT + +%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token <lex> FIELD_SELECTION %token <lex> LEFT_OP RIGHT_OP %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN @@ -160,10 +182,11 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) %type <interm> single_declaration init_declarator_list %type <interm> parameter_declaration parameter_declarator parameter_type_specifier -%type <interm.qualifier> parameter_qualifier +%type <interm.qualifier> parameter_qualifier parameter_type_qualifier +%type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id %type <interm.precision> precision_qualifier -%type <interm.type> type_qualifier fully_specified_type type_specifier +%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier %type <interm.type> type_specifier_no_prec type_specifier_nonarray %type <interm.type> struct_specifier %type <interm.field> struct_declarator @@ -173,6 +196,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype %type <interm> function_call_or_method +%type <lex> enter_struct + %start translation_unit %% @@ -183,43 +208,55 @@ identifier variable_identifier : IDENTIFIER { // The symbol table search was done in the lexical phase - const TSymbol* symbol = $1.symbol; - const TVariable* variable; - if (symbol == 0) { + const TSymbol *symbol = $1.symbol; + const TVariable *variable = 0; + + if (!symbol) + { context->error(@1, "undeclared identifier", $1.string->c_str()); context->recover(); - TType type(EbtFloat, EbpUndefined); - TVariable* fakeVariable = new TVariable($1.string, type); - context->symbolTable.insert(*fakeVariable); - variable = fakeVariable; - } else { - // This identifier can only be a variable type symbol - if (! symbol->isVariable()) { - context->error(@1, "variable expected", $1.string->c_str()); - context->recover(); - } - + } + else if (!symbol->isVariable()) + { + context->error(@1, "variable expected", $1.string->c_str()); + context->recover(); + } + else + { variable = static_cast<const TVariable*>(symbol); - if (context->symbolTable.findBuiltIn(variable->getName()) && + if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) && !variable->getExtension().empty() && - context->extensionErrorCheck(@1, variable->getExtension())) { + context->extensionErrorCheck(@1, variable->getExtension())) + { context->recover(); } } - // don't delete $1.string, it's used by error recovery, and the pool - // pop will reclaim the memory + if (!variable) + { + TType type(EbtFloat, EbpUndefined); + TVariable *fakeVariable = new TVariable($1.string, type); + context->symbolTable.declare(*fakeVariable); + variable = fakeVariable; + } - if (variable->getType().getQualifier() == EvqConst ) { + if (variable->getType().getQualifier() == EvqConst) + { ConstantUnion* constArray = variable->getConstPointer(); TType t(variable->getType()); $$ = context->intermediate.addConstantUnion(constArray, t, @1); - } else + } + else + { $$ = context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), @1); + } + + // don't delete $1.string, it's used by error recovery, and the pool + // pop will reclaim the memory } ; @@ -232,6 +269,11 @@ primary_expression unionArray->setIConst($1.i); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1); } + | UINTCONSTANT { + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setUConst($1.u); + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtUInt, EbpUndefined, EvqConst), @1); + } | FLOATCONSTANT { ConstantUnion *unionArray = new ConstantUnion[1]; unionArray->setFConst($1.f); @@ -258,104 +300,12 @@ postfix_expression $$ = $1; } | postfix_expression DOT identifier { - if ($1->isArray()) { - context->error(@3, "cannot apply dot operator to an array", "."); - context->recover(); - } - - if ($1->isVector()) { - TVectorFields fields; - if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, @3)) { - fields.num = 1; - fields.offsets[0] = 0; - context->recover(); - } - - if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields - $$ = context->addConstVectorNode(fields, $1, @3); - if ($$ == 0) { - context->recover(); - $$ = $1; - } - else - $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size())); - } else { - TString vectorString = *$3.string; - TIntermTyped* index = context->intermediate.addSwizzle(fields, @3); - $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, @2); - $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size())); - } - } else if ($1->isMatrix()) { - TMatrixFields fields; - if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, @3)) { - fields.wholeRow = false; - fields.wholeCol = false; - fields.row = 0; - fields.col = 0; - context->recover(); - } - - if (fields.wholeRow || fields.wholeCol) { - context->error(@2, " non-scalar fields not implemented yet", "."); - context->recover(); - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(0); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3); - $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2); - $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize())); - } else { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3); - $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2); - $$->setType(TType($1->getBasicType(), $1->getPrecision())); - } - } else if ($1->getBasicType() == EbtStruct) { - bool fieldFound = false; - const TFieldList& fields = $1->getType().getStruct()->fields(); - unsigned int i; - for (i = 0; i < fields.size(); ++i) { - if (fields[i]->name() == *$3.string) { - fieldFound = true; - break; - } - } - if (fieldFound) { - if ($1->getType().getQualifier() == EvqConst) { - $$ = context->addConstStruct(*$3.string, $1, @2); - if ($$ == 0) { - context->recover(); - $$ = $1; - } - else { - $$->setType(*fields[i]->type()); - // change the qualifier of the return type, not of the structure field - // as the structure definition is shared between various structures. - $$->getTypePointer()->setQualifier(EvqConst); - } - } else { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), @3); - $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2); - $$->setType(*fields[i]->type()); - } - } else { - context->error(@2, " no such field in structure", $3.string->c_str()); - context->recover(); - $$ = $1; - } - } else { - context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str()); - context->recover(); - $$ = $1; - } - // don't delete $3.string, it's from the pool + $$ = context->addFieldSelectionExpression($1, @2, *$3.string, @3); } | postfix_expression INC_OP { if (context->lValueErrorCheck(@2, "++", $1)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2); if ($$ == 0) { context->unaryOpError(@2, "++", $1->getCompleteString()); context->recover(); @@ -365,7 +315,7 @@ postfix_expression | postfix_expression DEC_OP { if (context->lValueErrorCheck(@2, "--", $1)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2); if ($$ == 0) { context->unaryOpError(@2, "--", $1->getCompleteString()); context->recover(); @@ -415,7 +365,7 @@ function_call // const TFunction* fnCandidate; bool builtIn; - fnCandidate = context->findFunction(@1, fnCall, &builtIn); + fnCandidate = context->findFunction(@1, fnCall, context->shaderVersion, &builtIn); if (fnCandidate) { // // A declared function. @@ -433,7 +383,7 @@ function_call // // Treat it like a built-in unary operator. // - $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1); if ($$ == 0) { std::stringstream extraInfoStream; extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString(); @@ -538,59 +488,7 @@ function_call_header function_identifier : type_specifier_nonarray { - // - // Constructor - // - TOperator op = EOpNull; - if ($1.userDef) { - op = EOpConstructStruct; - } else { - switch ($1.type) { - case EbtFloat: - if ($1.matrix) { - switch($1.size) { - case 2: op = EOpConstructMat2; break; - case 3: op = EOpConstructMat3; break; - case 4: op = EOpConstructMat4; break; - } - } else { - switch($1.size) { - case 1: op = EOpConstructFloat; break; - case 2: op = EOpConstructVec2; break; - case 3: op = EOpConstructVec3; break; - case 4: op = EOpConstructVec4; break; - } - } - break; - case EbtInt: - switch($1.size) { - case 1: op = EOpConstructInt; break; - case 2: op = EOpConstructIVec2; break; - case 3: op = EOpConstructIVec3; break; - case 4: op = EOpConstructIVec4; break; - } - break; - case EbtBool: - switch($1.size) { - case 1: op = EOpConstructBool; break; - case 2: op = EOpConstructBVec2; break; - case 3: op = EOpConstructBVec3; break; - case 4: op = EOpConstructBVec4; break; - } - break; - default: break; - } - if (op == EOpNull) { - context->error(@1, "cannot construct this type", getBasicString($1.type)); - context->recover(); - $1.type = EbtFloat; - op = EOpConstructFloat; - } - } - TString tempString; - TType type($1); - TFunction *function = new TFunction(&tempString, type, op); - $$ = function; + $$ = context->addConstructorFunc($1); } | IDENTIFIER { if (context->reservedErrorCheck(@1, *$1.string)) @@ -608,7 +506,7 @@ unary_expression | INC_OP unary_expression { if (context->lValueErrorCheck(@1, "++", $2)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1); if ($$ == 0) { context->unaryOpError(@1, "++", $2->getCompleteString()); context->recover(); @@ -618,7 +516,7 @@ unary_expression | DEC_OP unary_expression { if (context->lValueErrorCheck(@1, "--", $2)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1); if ($$ == 0) { context->unaryOpError(@1, "--", $2->getCompleteString()); context->recover(); @@ -627,7 +525,7 @@ unary_expression } | unary_operator unary_expression { if ($1.op != EOpNull) { - $$ = context->intermediate.addUnaryMath($1.op, $2, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath($1.op, $2, @1); if ($$ == 0) { const char* errorOp = ""; switch($1.op) { @@ -655,7 +553,7 @@ unary_operator multiplicative_expression : unary_expression { $$ = $1; } | multiplicative_expression STAR unary_expression { - $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -663,7 +561,7 @@ multiplicative_expression } } | multiplicative_expression SLASH unary_expression { - $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -675,7 +573,7 @@ multiplicative_expression additive_expression : multiplicative_expression { $$ = $1; } | additive_expression PLUS multiplicative_expression { - $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -683,7 +581,7 @@ additive_expression } } | additive_expression DASH multiplicative_expression { - $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -699,7 +597,7 @@ shift_expression relational_expression : shift_expression { $$ = $1; } | relational_expression LEFT_ANGLE shift_expression { - $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -709,7 +607,7 @@ relational_expression } } | relational_expression RIGHT_ANGLE shift_expression { - $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -719,7 +617,7 @@ relational_expression } } | relational_expression LE_OP shift_expression { - $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -729,7 +627,7 @@ relational_expression } } | relational_expression GE_OP shift_expression { - $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -743,7 +641,7 @@ relational_expression equality_expression : relational_expression { $$ = $1; } | equality_expression EQ_OP relational_expression { - $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -753,7 +651,7 @@ equality_expression } } | equality_expression NE_OP relational_expression { - $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -779,7 +677,7 @@ inclusive_or_expression logical_and_expression : inclusive_or_expression { $$ = $1; } | logical_and_expression AND_OP inclusive_or_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -793,7 +691,7 @@ logical_and_expression logical_xor_expression : logical_and_expression { $$ = $1; } | logical_xor_expression XOR_OP logical_and_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -807,7 +705,7 @@ logical_xor_expression logical_or_expression : logical_xor_expression { $$ = $1; } | logical_or_expression OR_OP logical_xor_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -880,6 +778,14 @@ constant_expression } ; +enter_struct + : IDENTIFIER LEFT_BRACE { + if (context->enterStructDeclaration(@1, *$1.string)) + context->recover(); + $$ = $1; + } + ; + declaration : function_prototype SEMICOLON { TFunction &function = *($1.function); @@ -924,6 +830,22 @@ declaration } $$ = 0; } + | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { + ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$); + } + | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { + ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$); + } + | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON { + ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6); + } + | type_qualifier SEMICOLON { + context->parseGlobalLayoutQualifier($1); + $$ = 0; + } ; function_prototype @@ -936,7 +858,7 @@ function_prototype // // Redeclarations are allowed. But, return types and parameter qualifiers must match. // - TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName())); + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName(), context->shaderVersion)); if (prevDec) { if (prevDec->getReturnType() != $1->getReturnType()) { context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString()); @@ -953,7 +875,7 @@ function_prototype // // Check for previously declared variables using the same name. // - TSymbol *prevSym = context->symbolTable.find($1->getName()); + TSymbol *prevSym = context->symbolTable.find($1->getName(), context->shaderVersion); if (prevSym) { if (!prevSym->isFunction()) @@ -1080,9 +1002,9 @@ parameter_declaration // // Type + name // - : type_qualifier parameter_qualifier parameter_declarator { + : parameter_type_qualifier parameter_qualifier parameter_declarator { $$ = $3; - if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type)) + if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) context->recover(); } | parameter_qualifier parameter_declarator { @@ -1095,9 +1017,9 @@ parameter_declaration // // Only type // - | type_qualifier parameter_qualifier parameter_type_specifier { + | parameter_type_qualifier parameter_qualifier parameter_type_specifier { $$ = $3; - if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type)) + if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) context->recover(); } | parameter_qualifier parameter_type_specifier { @@ -1136,173 +1058,46 @@ init_declarator_list $$ = $1; } | init_declarator_list COMMA identifier { - if ($1.type.type == EbtInvariant && !$3.symbol) - { - context->error(@3, "undeclared identifier declared as invariant", $3.string->c_str()); - context->recover(); - } - - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3); - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3); - - if (context->structQualifierErrorCheck(@3, $$.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false)) - context->recover(); - - TVariable* variable = 0; - if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable)) - context->recover(); - if (symbol && variable) - symbol->setId(variable->getUniqueId()); + $$ = $1; + $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, $3.symbol, @3, *$3.string); } | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET { - if (context->structQualifierErrorCheck(@3, $1.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true)) - context->recover(); - $$ = $1; - - if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type)) - context->recover(); - else { - $1.type.setArray(true); - TVariable* variable; - if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable)) - context->recover(); - } + context->parseArrayDeclarator($$.type, @3, *$3.string, @4, NULL, NULL); } | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - if (context->structQualifierErrorCheck(@3, $1.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true)) - context->recover(); - $$ = $1; - - if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck(@4, $5, size)) - context->recover(); - $1.type.setArray(true, size); - TVariable* variable = 0; - if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable)) - context->recover(); - TType type = TType($1.type); - type.setArraySize(size); - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, @3), @3); - } + $$.intermAggregate = context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $1.intermNode, $5); } | init_declarator_list COMMA identifier EQUAL initializer { - if (context->structQualifierErrorCheck(@3, $1.type)) - context->recover(); - $$ = $1; - - TIntermNode* intermNode; - if (!context->executeInitializer(@3, *$3.string, $1.type, $5, intermNode)) { - // - // build the intermediate representation - // - if (intermNode) - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4); - else - $$.intermAggregate = $1.intermAggregate; - } else { - context->recover(); - $$.intermAggregate = 0; - } + $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); } ; single_declaration : fully_specified_type { $$.type = $1; - $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), @1), @1); + $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, ""); } | fully_specified_type identifier { - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2); - $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); - - if (context->structQualifierErrorCheck(@2, $$.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false)) - context->recover(); - - $$.type = $1; - - TVariable* variable = 0; - if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable)) - context->recover(); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); + $$.type = $1; + $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); } | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET { context->error(@2, "unsized array declarations not supported", $2.string->c_str()); context->recover(); - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2); - $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); $$.type = $1; + $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); } | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - TType type = TType($1); - int size; - if (context->arraySizeErrorCheck(@2, $4, size)) - context->recover(); - type.setArraySize(size); - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2); - $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); - - if (context->structQualifierErrorCheck(@2, $1)) - context->recover(); - - if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true)) - context->recover(); - $$.type = $1; - - if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck(@3, $4, size)) - context->recover(); - - $1.setArray(true, size); - TVariable* variable = 0; - if (context->arrayErrorCheck(@3, *$2.string, $1, variable)) - context->recover(); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); - } + $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); } | fully_specified_type identifier EQUAL initializer { - if (context->structQualifierErrorCheck(@2, $1)) - context->recover(); - $$.type = $1; - - TIntermNode* intermNode; - if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) { - // - // Build intermediate representation - // - if(intermNode) - $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3); - else - $$.intermAggregate = 0; - } else { - context->recover(); - $$.intermAggregate = 0; - } + $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); } | INVARIANT IDENTIFIER { VERTEX_ONLY("invariant declaration", @1); @@ -1335,38 +1130,35 @@ fully_specified_type } } | type_qualifier type_specifier { - if ($2.array) { - context->error(@2, "not supported", "first-class array"); - context->recover(); - $2.setArray(false); - } + $$ = context->addFullySpecifiedType($1.qualifier, $1.layoutQualifier, $2); + } + ; - if ($1.qualifier == EvqAttribute && - ($2.type == EbtBool || $2.type == EbtInt)) { - context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier)); - context->recover(); - } - if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) && - ($2.type == EbtBool || $2.type == EbtInt)) { - context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier)); - context->recover(); - } - $$ = $2; - $$.qualifier = $1.qualifier; +interpolation_qualifier + : SMOOTH { + $$.qualifier = EvqSmooth; + } + | FLAT { + $$.qualifier = EvqFlat; } ; -type_qualifier +parameter_type_qualifier : CONST_QUAL { - $$.setBasic(EbtVoid, EvqConst, @1); + $$ = EvqConst; } - | ATTRIBUTE { + ; + +type_qualifier + : ATTRIBUTE { VERTEX_ONLY("attribute", @1); + ES2_ONLY("attribute", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute")) context->recover(); $$.setBasic(EbtVoid, EvqAttribute, @1); } | VARYING { + ES2_ONLY("varying", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) context->recover(); if (context->shaderType == SH_VERTEX_SHADER) @@ -1375,6 +1167,7 @@ type_qualifier $$.setBasic(EbtVoid, EvqVaryingIn, @1); } | INVARIANT VARYING { + ES2_ONLY("varying", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) context->recover(); if (context->shaderType == SH_VERTEX_SHADER) @@ -1382,10 +1175,68 @@ type_qualifier else $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1); } + | storage_qualifier { + if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { + context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); + context->recover(); + } else { + $$.setBasic(EbtVoid, $1.qualifier, @1); + } + } + | interpolation_qualifier storage_qualifier { + $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier); + } + | interpolation_qualifier { + context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier)); + context->recover(); + + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtVoid, qual, @1); + } + | layout_qualifier { + $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.layoutQualifier = $1; + } + | layout_qualifier storage_qualifier { + $$.setBasic(EbtVoid, $2.qualifier, @2); + $$.layoutQualifier = $1; + } + ; + +storage_qualifier + : CONST_QUAL { + $$.qualifier = EvqConst; + } + | IN_QUAL { + ES3_ONLY("in", @1, "storage qualifier"); + $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + } + | OUT_QUAL { + ES3_ONLY("out", @1, "storage qualifier"); + $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + } + | CENTROID IN_QUAL { + ES3_ONLY("centroid in", @1, "storage qualifier"); + if (context->shaderType == SH_VERTEX_SHADER) + { + context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); + context->recover(); + } + $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + } + | CENTROID OUT_QUAL { + ES3_ONLY("centroid out", @1, "storage qualifier"); + if (context->shaderType == SH_FRAGMENT_SHADER) + { + context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); + context->recover(); + } + $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + } | UNIFORM { if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) context->recover(); - $$.setBasic(EbtVoid, EvqUniform, @1); + $$.qualifier = EvqUniform; } ; @@ -1403,6 +1254,11 @@ type_specifier | precision_qualifier type_specifier_no_prec { $$ = $2; $$.precision = $1; + + if (!SupportsPrecision($2.type)) { + context->error(@1, "illegal type for precision qualifier", getBasicString($2.type)); + context->recover(); + } } ; @@ -1418,6 +1274,34 @@ precision_qualifier } ; +layout_qualifier + : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { + ES3_ONLY("layout", @1, "qualifier"); + $$ = $3; + } + ; + +layout_qualifier_id_list + : layout_qualifier_id { + $$ = $1; + } + | layout_qualifier_id_list COMMA layout_qualifier_id { + $$ = context->joinLayoutQualifiers($1, $3); + } + ; + +layout_qualifier_id + : IDENTIFIER { + $$ = context->parseLayoutQualifier(*$1.string, @1); + } + | IDENTIFIER EQUAL INTCONSTANT { + $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + } + | IDENTIFIER EQUAL UINTCONSTANT { + $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + } + ; + type_specifier_no_prec : type_specifier_nonarray { $$ = $1; @@ -1449,6 +1333,10 @@ type_specifier_nonarray TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtInt, qual, @1); } + | UINT_TYPE { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + } | BOOL_TYPE { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtBool, qual, @1); @@ -1498,29 +1386,126 @@ type_specifier_nonarray $$.setBasic(EbtInt, qual, @1); $$.setAggregate(4); } + | UVEC2 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + $$.setAggregate(2); + } + | UVEC3 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + $$.setAggregate(3); + } + | UVEC4 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + $$.setAggregate(4); + } | MATRIX2 { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtFloat, qual, @1); - $$.setAggregate(2, true); + $$.setMatrix(2, 2); } | MATRIX3 { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtFloat, qual, @1); - $$.setAggregate(3, true); + $$.setMatrix(3, 3); } | MATRIX4 { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtFloat, qual, @1); - $$.setAggregate(4, true); + $$.setMatrix(4, 4); + } + | MATRIX2x3 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(2, 3); + } + | MATRIX3x2 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(3, 2); + } + | MATRIX2x4 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(2, 4); + } + | MATRIX4x2 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(4, 2); + } + | MATRIX3x4 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(3, 4); + } + | MATRIX4x3 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(4, 3); } | SAMPLER2D { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSampler2D, qual, @1); } + | SAMPLER3D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler3D, qual, @1); + } | SAMPLERCUBE { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerCube, qual, @1); } + | SAMPLER2DARRAY { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DArray, qual, @1); + } + | ISAMPLER2D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler2D, qual, @1); + } + | ISAMPLER3D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler3D, qual, @1); + } + | ISAMPLERCUBE { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISamplerCube, qual, @1); + } + | ISAMPLER2DARRAY { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler2DArray, qual, @1); + } + | USAMPLER2D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler2D, qual, @1); + } + | USAMPLER3D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler3D, qual, @1); + } + | USAMPLERCUBE { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSamplerCube, qual, @1); + } + | USAMPLER2DARRAY { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler2DArray, qual, @1); + } + | SAMPLER2DSHADOW { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DShadow, qual, @1); + } + | SAMPLERCUBESHADOW { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSamplerCubeShadow, qual, @1); + } + | SAMPLER2DARRAYSHADOW { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DArrayShadow, qual, @1); + } | SAMPLER_EXTERNAL_OES { if (!context->supportsExtension("GL_OES_EGL_image_external")) { context->error(@1, "unsupported type", "samplerExternalOES"); @@ -1555,24 +1540,10 @@ type_specifier_nonarray struct_specifier : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { - if (context->reservedErrorCheck(@2, *$2.string)) - context->recover(); - - TType* structure = new TType(new TStructure($2.string, $5)); - TVariable* userTypeDef = new TVariable($2.string, *structure, true); - if (! context->symbolTable.insert(*userTypeDef)) { - context->error(@2, "redefinition", $2.string->c_str(), "struct"); - context->recover(); - } - $$.setBasic(EbtStruct, EvqTemporary, @1); - $$.userDef = structure; - context->exitStructDeclaration(); + $$ = context->addStructure(@1, @2, $2.string, $5); } | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { - TType* structure = new TType(new TStructure(NewPoolTString(""), $4)); - $$.setBasic(EbtStruct, EvqTemporary, @1); - $$.userDef = structure; - context->exitStructDeclaration(); + $$ = context->addStructure(@1, @$, NewPoolTString(""), $4); } ; @@ -1597,34 +1568,13 @@ struct_declaration_list struct_declaration : type_specifier struct_declarator_list SEMICOLON { - $$ = $2; - - if (context->voidErrorCheck(@1, (*$2)[0]->name(), $1)) { - context->recover(); - } - for (unsigned int i = 0; i < $$->size(); ++i) { - // - // Careful not to replace already known aspects of type, like array-ness - // - TType* type = (*$$)[i]->type(); - type->setBasicType($1.type); - type->setNominalSize($1.size); - type->setMatrix($1.matrix); - type->setPrecision($1.precision); - - // don't allow arrays of arrays - if (type->isArray()) { - if (context->arrayTypeErrorCheck(@1, $1)) - context->recover(); - } - if ($1.array) - type->setArraySize($1.arraySize); - if ($1.userDef) - type->setStruct($1.userDef->getStruct()); - - if (context->structNestingErrorCheck(@1, *(*$$)[i])) - context->recover(); - } + $$ = context->addStructDeclaratorList($1, $2); + } + | type_qualifier type_specifier struct_declarator_list SEMICOLON { + // ES3 Only, but errors should be handled elsewhere + $2.qualifier = $1.qualifier; + $2.layoutQualifier = $1.layoutQualifier; + $$ = context->addStructDeclaratorList($2, $3); } ; @@ -1644,19 +1594,19 @@ struct_declarator context->recover(); TType* type = new TType(EbtVoid, EbpUndefined); - $$ = new TField(type, $1.string); + $$ = new TField(type, $1.string, @1); } | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { if (context->reservedErrorCheck(@1, *$1.string)) context->recover(); TType* type = new TType(EbtVoid, EbpUndefined); - int size = 0; + int size; if (context->arraySizeErrorCheck(@3, $3, size)) context->recover(); type->setArraySize(size); - $$ = new TField(type, $1.string); + $$ = new TField(type, $1.string, @1); } ; @@ -1890,7 +1840,7 @@ function_definition : function_prototype { TFunction* function = $1.function; - const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName()); + const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion); if (builtIn) { @@ -1898,7 +1848,7 @@ function_definition context->recover(); } - TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName())); + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName(), context->shaderVersion)); // // Note: 'prevDec' could be 'function' if this is the first time we've seen function // as it would have just been put in the symbol table. Otherwise, we're looking up @@ -1949,7 +1899,7 @@ function_definition // // Insert the parameters with name in the symbol table. // - if (! context->symbolTable.insert(*variable)) { + if (! context->symbolTable.declare(*variable)) { context->error(@1, "redefinition", variable->getName().c_str()); context->recover(); delete variable; @@ -1961,9 +1911,8 @@ function_definition paramNodes = context->intermediate.growAggregate( paramNodes, context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), - @1), + variable->getName(), + variable->getType(), @1), @1); } else { paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1); diff --git a/chromium/third_party/angle/src/compiler/glslang_lex.cpp b/chromium/third_party/angle/src/compiler/translator/glslang_lex.cpp index de3d82bcd80..5cfbba63eb3 100644 --- a/chromium/third_party/angle/src/compiler/glslang_lex.cpp +++ b/chromium/third_party/angle/src/compiler/translator/glslang_lex.cpp @@ -1,6 +1,6 @@ #line 17 "./glslang.l" // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -30,7 +30,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -76,7 +76,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -107,6 +106,8 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif +#endif /* ! C99 */ + #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -197,6 +198,11 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; typedef size_t yy_size_t; #endif +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 @@ -360,7 +366,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(n) 1 +#define yywrap(yyscanner) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -384,8 +390,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 147 -#define YY_END_OF_BUFFER 148 +#define YY_NUM_RULES 237 +#define YY_END_OF_BUFFER 238 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -393,57 +399,98 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[443] = +static yyconst flex_int16_t yy_accept[813] = { 0, - 0, 0, 148, 146, 145, 145, 132, 138, 143, 127, - 128, 136, 135, 124, 133, 131, 137, 96, 96, 125, - 121, 139, 126, 140, 144, 93, 129, 130, 142, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 122, - 141, 123, 134, 118, 104, 123, 112, 107, 102, 110, - 100, 111, 101, 99, 103, 98, 95, 96, 0, 0, - 130, 122, 129, 119, 115, 117, 116, 120, 93, 108, - 114, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 12, 93, 93, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 93, 15, 17, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 109, 113, 0, 98, 0, 0, - 97, 94, 105, 106, 45, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 13, 93, 93, 93, 93, 93, 93, - 93, 93, 21, 93, 93, 93, 93, 93, 93, 93, - 93, 18, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 93, 0, 99, 0, 98, 93, - 23, 93, 93, 90, 93, 93, 93, 93, 93, 93, - 93, 16, 48, 93, 93, 93, 64, 93, 93, 53, - 68, 93, 93, 93, 93, 93, 93, 93, 93, 65, - 4, 28, 29, 30, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 51, 24, 93, 93, 93, 93, 93, 93, 31, 32, - 33, 22, 93, 93, 93, 10, 37, 38, 39, 46, - 7, 93, 93, 93, 93, 77, 78, 79, 93, 25, - 69, 20, 80, 81, 82, 2, 74, 75, 76, 93, - - 19, 72, 93, 93, 34, 35, 36, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 66, 93, 93, 93, - 93, 93, 93, 93, 93, 47, 93, 92, 93, 93, - 14, 93, 93, 93, 93, 67, 61, 56, 93, 93, - 93, 93, 93, 73, 52, 93, 59, 27, 93, 89, - 60, 44, 71, 54, 93, 93, 93, 93, 93, 93, - 93, 93, 55, 26, 93, 93, 93, 3, 93, 93, - 93, 93, 93, 49, 8, 93, 9, 93, 93, 11, - 62, 93, 93, 93, 57, 93, 93, 93, 93, 93, - 93, 50, 70, 58, 6, 63, 1, 91, 5, 83, - - 40, 84, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 41, 93, 93, 93, 93, 93, - 93, 93, 43, 93, 87, 93, 93, 93, 93, 93, - 85, 93, 86, 93, 93, 93, 93, 93, 93, 42, - 88, 0 + 0, 0, 238, 236, 235, 235, 222, 228, 233, 217, + 218, 226, 225, 214, 223, 221, 227, 180, 180, 215, + 211, 229, 216, 230, 234, 177, 219, 220, 232, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 212, + 231, 213, 224, 208, 194, 213, 202, 197, 192, 200, + 190, 201, 191, 186, 193, 185, 179, 180, 0, 183, + 0, 220, 212, 219, 209, 205, 207, 206, 210, 177, + 198, 204, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 12, 177, 177, 177, 177, 177, + + 177, 177, 177, 177, 177, 177, 177, 177, 15, 177, + 177, 23, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 199, 203, 0, 189, 185, + 0, 188, 182, 0, 184, 178, 195, 196, 177, 136, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 13, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 27, 177, 177, 177, 177, 177, + + 177, 177, 177, 177, 177, 177, 24, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 0, 186, 0, 185, 187, 181, 177, 177, 177, + 30, 177, 177, 18, 174, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 16, 139, 177, 177, 177, + 177, 21, 177, 177, 143, 155, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 152, 4, + 35, 36, 37, 177, 177, 177, 177, 177, 177, 177, + + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 142, 31, 177, + 177, 28, 177, 177, 177, 177, 177, 177, 177, 47, + 48, 49, 29, 177, 177, 177, 177, 177, 177, 10, + 53, 54, 55, 177, 137, 177, 177, 7, 177, 177, + 177, 177, 164, 165, 166, 177, 32, 177, 156, 26, + 167, 168, 169, 2, 161, 162, 163, 177, 177, 177, + 25, 159, 177, 177, 177, 50, 51, 52, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 86, + 177, 177, 177, 177, 177, 177, 177, 153, 177, 177, + + 177, 177, 177, 177, 177, 177, 177, 177, 177, 138, + 177, 177, 176, 56, 57, 58, 177, 177, 14, 177, + 91, 177, 177, 177, 177, 89, 177, 177, 177, 154, + 149, 92, 177, 177, 177, 177, 177, 177, 144, 177, + 177, 177, 78, 38, 41, 43, 42, 39, 45, 44, + 46, 40, 177, 177, 177, 177, 160, 135, 177, 177, + 147, 177, 177, 177, 34, 87, 173, 22, 148, 77, + 177, 158, 17, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 19, 33, 177, + 177, 177, 177, 177, 177, 93, 94, 95, 177, 177, + + 177, 177, 177, 3, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 140, 177, 177, 177, 177, + 177, 8, 177, 177, 9, 177, 177, 177, 177, 20, + 79, 11, 150, 97, 98, 99, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 145, 177, + 177, 177, 81, 83, 80, 177, 177, 177, 177, 177, + 177, 177, 141, 101, 102, 103, 177, 177, 157, 177, + 146, 177, 177, 6, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 96, 151, 1, 177, 177, 177, 177, + 177, 175, 177, 90, 5, 170, 59, 62, 177, 177, + + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 82, 177, 177, 177, 177, 100, 177, 177, 177, + 177, 177, 120, 66, 67, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 88, 177, + 177, 177, 104, 122, 70, 71, 177, 177, 84, 177, + 177, 177, 177, 177, 177, 177, 115, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 129, 177, 177, + 177, 177, 60, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 116, 105, 177, 106, 177, + 177, 177, 130, 177, 177, 68, 177, 177, 177, 177, + + 177, 177, 177, 177, 177, 177, 177, 177, 177, 117, + 177, 177, 131, 177, 177, 72, 107, 108, 177, 111, + 177, 112, 177, 177, 177, 177, 177, 85, 177, 177, + 177, 177, 64, 177, 63, 126, 177, 177, 109, 110, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 124, 127, 118, 177, 65, 177, 177, 177, 177, 177, + 177, 177, 177, 125, 128, 177, 177, 121, 69, 177, + 177, 171, 177, 177, 177, 74, 177, 177, 123, 73, + 177, 177, 177, 177, 177, 177, 132, 177, 177, 177, + 177, 177, 177, 133, 177, 177, 177, 75, 177, 134, + + 113, 114, 177, 177, 177, 61, 177, 177, 172, 119, + 76, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -454,14 +501,14 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, 20, 21, 21, 22, 23, 24, - 25, 26, 27, 1, 28, 28, 29, 30, 31, 28, - 32, 32, 32, 32, 32, 32, 32, 32, 33, 32, - 32, 34, 35, 32, 32, 32, 32, 36, 32, 32, - 37, 1, 38, 39, 32, 1, 40, 41, 42, 43, - - 44, 45, 46, 47, 48, 32, 49, 50, 51, 52, - 53, 54, 32, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 1, 1, 1, 1, + 25, 26, 27, 1, 28, 29, 30, 31, 32, 33, + 34, 34, 34, 34, 34, 34, 35, 34, 36, 34, + 34, 37, 38, 34, 39, 34, 34, 40, 34, 34, + 41, 1, 42, 43, 44, 1, 45, 46, 47, 48, + + 49, 50, 51, 52, 53, 34, 54, 55, 56, 57, + 58, 59, 34, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -478,200 +525,323 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[68] = +static yyconst flex_int32_t yy_meta[73] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 1, 1, 1, 1 + 2, 1, 1, 1, 1, 1, 1, 3, 3, 3, + 3, 2, 2, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 4, 3, 3, 3, 3, 2, 2, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, + 1, 1 } ; -static yyconst flex_int16_t yy_base[445] = +static yyconst flex_int16_t yy_base[817] = { 0, - 0, 0, 587, 588, 588, 588, 561, 43, 64, 588, - 588, 560, 61, 588, 60, 58, 559, 77, 86, 557, - 588, 104, 557, 55, 588, 0, 588, 588, 75, 26, - 57, 82, 83, 73, 93, 528, 97, 95, 527, 44, - 71, 521, 104, 534, 110, 116, 35, 111, 530, 588, - 114, 588, 588, 588, 588, 588, 588, 588, 588, 588, - 588, 588, 588, 165, 588, 172, 202, 211, 233, 0, - 588, 588, 588, 551, 588, 588, 588, 550, 0, 588, - 588, 523, 516, 519, 527, 526, 513, 528, 515, 521, - 509, 506, 519, 506, 503, 503, 509, 497, 108, 502, - - 512, 498, 504, 507, 508, 0, 145, 507, 113, 493, - 506, 497, 499, 489, 503, 500, 502, 485, 490, 487, - 476, 157, 484, 489, 485, 487, 476, 479, 118, 484, - 476, 488, 70, 481, 588, 588, 246, 253, 270, 219, - 283, 0, 588, 588, 0, 473, 477, 486, 483, 467, - 467, 119, 482, 479, 479, 477, 474, 466, 472, 459, - 470, 456, 472, 0, 469, 457, 464, 461, 465, 458, - 447, 446, 459, 462, 459, 454, 445, 188, 450, 453, - 444, 441, 445, 451, 442, 433, 436, 434, 444, 430, - 428, 441, 427, 429, 426, 437, 436, 124, 431, 426, - - 415, 258, 433, 435, 424, 290, 297, 304, 311, 425, - 0, 423, 275, 0, 415, 413, 421, 410, 427, 416, - 316, 0, 0, 410, 420, 420, 0, 405, 319, 0, - 0, 407, 322, 408, 402, 401, 402, 401, 325, 0, - 0, 0, 0, 0, 397, 398, 403, 394, 407, 402, - 401, 393, 397, 389, 392, 396, 401, 387, 399, 390, - 0, 0, 396, 385, 385, 390, 389, 386, 0, 0, - 0, 0, 376, 388, 390, 0, 0, 0, 0, 0, - 0, 378, 379, 373, 383, 0, 0, 0, 374, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 381, - - 0, 0, 379, 375, 0, 0, 0, 371, 367, 372, - 362, 375, 361, 374, 363, 370, 0, 368, 370, 354, - 356, 362, 368, 363, 351, 0, 353, 0, 352, 355, - 0, 344, 343, 343, 356, 0, 358, 0, 357, 356, - 341, 354, 341, 0, 0, 344, 0, 0, 336, 0, - 0, 0, 0, 0, 333, 344, 337, 343, 340, 335, - 327, 339, 0, 0, 332, 339, 328, 0, 337, 334, - 324, 329, 332, 0, 0, 332, 0, 330, 329, 0, - 0, 328, 314, 326, 0, 317, 338, 337, 336, 307, - 303, 0, 0, 0, 0, 0, 0, 0, 0, 328, - - 166, 325, 316, 299, 308, 310, 306, 308, 307, 306, - 309, 306, 256, 253, 0, 228, 238, 222, 235, 203, - 207, 204, 212, 191, 0, 201, 165, 167, 153, 161, - 0, 170, 0, 175, 151, 141, 100, 114, 59, 0, - 0, 588, 359, 113 + 0, 0, 941, 942, 942, 942, 915, 48, 69, 942, + 942, 914, 66, 942, 65, 63, 913, 82, 136, 911, + 942, 82, 911, 60, 942, 0, 942, 942, 67, 58, + 51, 68, 75, 61, 105, 877, 114, 79, 67, 44, + 89, 871, 101, 884, 121, 127, 136, 143, 36, 942, + 112, 942, 942, 942, 942, 942, 942, 942, 942, 942, + 942, 942, 942, 158, 942, 163, 163, 0, 199, 942, + 0, 942, 942, 942, 907, 942, 942, 942, 906, 0, + 942, 942, 868, 873, 80, 870, 878, 877, 864, 867, + 878, 171, 872, 860, 857, 870, 857, 854, 854, 860, + + 75, 176, 854, 864, 850, 856, 859, 860, 0, 852, + 862, 177, 861, 856, 837, 105, 841, 854, 845, 112, + 838, 178, 850, 852, 185, 841, 838, 827, 836, 177, + 185, 840, 836, 838, 827, 830, 124, 145, 197, 839, + 827, 839, 190, 832, 831, 942, 942, 239, 942, 220, + 256, 942, 942, 263, 270, 185, 942, 942, 830, 0, + 826, 821, 825, 834, 831, 243, 815, 815, 826, 818, + 143, 828, 825, 825, 823, 820, 812, 818, 805, 803, + 815, 801, 817, 0, 814, 802, 809, 806, 810, 811, + 804, 801, 790, 789, 802, 805, 793, 801, 789, 795, + + 786, 244, 791, 794, 785, 792, 781, 785, 776, 790, + 789, 780, 786, 235, 770, 773, 771, 781, 771, 766, + 764, 766, 776, 762, 764, 761, 772, 771, 774, 756, + 244, 764, 760, 758, 767, 746, 281, 764, 766, 755, + 747, 291, 298, 306, 317, 942, 942, 744, 754, 753, + 0, 751, 311, 0, 0, 744, 742, 742, 743, 738, + 746, 735, 752, 741, 322, 0, 0, 735, 745, 744, + 744, 0, 729, 325, 0, 0, 731, 328, 738, 739, + 730, 724, 723, 724, 723, 723, 334, 718, 0, 0, + 714, 713, 712, 714, 715, 720, 714, 710, 723, 718, + + 718, 716, 715, 709, 703, 705, 704, 708, 700, 703, + 698, 706, 711, 699, 696, 708, 699, 0, 0, 705, + 701, 0, 693, 693, 698, 689, 696, 337, 693, 0, + 0, 0, 0, 683, 695, 694, 693, 694, 694, 0, + 0, 0, 0, 681, 0, 689, 680, 0, 679, 680, + 674, 684, 0, 0, 0, 675, 0, 671, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 681, 341, 680, + 0, 0, 678, 674, 671, 0, 0, 0, 663, 343, + 346, 355, 668, 664, 669, 660, 658, 671, 656, 0, + 656, 669, 658, 654, 660, 655, 662, 0, 660, 657, + + 661, 645, 643, 646, 652, 658, 653, 652, 640, 0, + 642, 643, 0, 0, 0, 0, 640, 643, 0, 637, + 0, 650, 630, 639, 634, 0, 627, 627, 640, 0, + 642, 0, 359, 655, 654, 653, 620, 619, 0, 636, + 635, 630, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 619, 632, 619, 616, 0, 0, 621, 620, + 0, 617, 624, 623, 0, 609, 0, 0, 0, 0, + 606, 0, 0, 605, 616, 362, 609, 615, 614, 611, + 606, 603, 596, 596, 609, 594, 606, 0, 0, 599, + 622, 621, 620, 587, 586, 355, 356, 0, 598, 601, + + 599, 588, 584, 0, 596, 593, 592, 582, 581, 571, + 588, 574, 369, 582, 585, 0, 602, 601, 600, 567, + 566, 0, 580, 567, 0, 577, 570, 571, 574, 0, + 0, 0, 0, 594, 593, 0, 570, 573, 558, 565, + 556, 563, 564, 564, 563, 549, 379, 561, 0, 562, + 551, 550, 0, 0, 0, 575, 574, 573, 540, 539, + 535, 543, 0, 571, 570, 0, 547, 550, 0, 386, + 0, 528, 537, 0, 533, 532, 541, 541, 529, 543, + 527, 541, 536, 0, 0, 0, 553, 552, 551, 518, + 517, 0, 517, 0, 0, 362, 382, 541, 527, 530, + + 513, 525, 513, 512, 521, 521, 538, 537, 536, 503, + 502, 0, 502, 503, 502, 512, 0, 515, 511, 513, + 509, 496, 527, 377, 0, 504, 507, 499, 491, 498, + 489, 510, 498, 494, 496, 494, 494, 493, 0, 481, + 480, 490, 0, 510, 390, 0, 487, 490, 0, 490, + 489, 473, 465, 473, 463, 471, 0, 468, 467, 488, + 476, 474, 474, 458, 461, 475, 459, 490, 470, 471, + 468, 465, 475, 452, 466, 465, 449, 448, 447, 468, + 456, 454, 454, 435, 434, 0, 462, 434, 460, 432, + 436, 435, 466, 446, 443, 0, 442, 445, 441, 443, + + 427, 424, 437, 422, 423, 430, 424, 413, 412, 0, + 418, 417, 448, 428, 425, 0, 0, 0, 421, 0, + 420, 0, 426, 425, 409, 406, 407, 0, 399, 407, + 397, 403, 424, 403, 0, 0, 415, 414, 0, 0, + 413, 412, 396, 393, 394, 408, 407, 384, 383, 389, + 0, 0, 410, 382, 408, 400, 392, 378, 60, 89, + 105, 143, 173, 0, 0, 216, 217, 0, 0, 222, + 243, 0, 244, 234, 259, 0, 291, 330, 0, 0, + 323, 311, 323, 315, 361, 362, 0, 363, 348, 389, + 355, 358, 359, 0, 378, 380, 371, 0, 392, 0, + + 0, 0, 373, 374, 368, 0, 369, 370, 0, 0, + 0, 942, 434, 437, 438, 439 } ; -static yyconst flex_int16_t yy_def[445] = +static yyconst flex_int16_t yy_def[817] = { 0, - 442, 1, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 443, 442, 442, 442, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 444, - 442, 442, 442, 442, 442, 442, 442, 442, 443, 442, - 442, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 442, 442, 442, 442, 442, 442, - 442, 444, 442, 442, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - - 443, 443, 443, 443, 443, 442, 442, 442, 442, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 0, 442, 442 + 812, 1, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 813, 812, 812, 812, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 814, 812, 815, 18, 19, 812, 812, + 816, 812, 812, 812, 812, 812, 812, 812, 812, 813, + 812, 812, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 812, 812, 812, 812, 815, + 812, 812, 812, 812, 812, 816, 812, 812, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 812, 812, 812, 812, 812, 812, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 813, 0, 812, 812, 812, 812 } ; -static yyconst flex_int16_t yy_nxt[656] = +static yyconst flex_int16_t yy_nxt[1015] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19, 19, 19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 26, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 26, 26, 26, 50, 51, 52, 53, 55, 56, 57, - 60, 62, 64, 64, 64, 64, 64, 64, 64, 77, - 78, 82, 83, 110, 63, 61, 129, 111, 58, 66, - 130, 67, 67, 67, 67, 67, 67, 68, 66, 80, - - 68, 68, 68, 68, 68, 68, 68, 69, 72, 84, - 112, 85, 70, 81, 142, 86, 69, 203, 441, 204, - 69, 87, 94, 113, 95, 73, 90, 74, 75, 69, - 91, 88, 97, 96, 89, 92, 103, 70, 135, 106, - 98, 93, 99, 115, 104, 100, 107, 162, 440, 119, - 131, 101, 439, 108, 132, 105, 120, 121, 116, 125, - 163, 117, 126, 133, 176, 198, 122, 123, 264, 124, - 127, 438, 177, 199, 216, 217, 265, 128, 136, 64, - 64, 64, 64, 64, 64, 64, 138, 138, 138, 138, - 138, 138, 138, 437, 170, 137, 190, 171, 172, 406, - - 407, 173, 139, 174, 242, 243, 244, 436, 137, 435, - 434, 191, 433, 432, 66, 139, 67, 67, 67, 67, - 67, 67, 68, 66, 431, 68, 68, 68, 68, 68, - 68, 68, 69, 141, 141, 141, 141, 141, 141, 141, - 430, 69, 140, 429, 140, 69, 428, 141, 141, 141, - 141, 141, 141, 141, 69, 206, 427, 206, 426, 425, - 207, 207, 207, 207, 207, 207, 207, 138, 138, 138, - 138, 138, 138, 138, 269, 270, 271, 424, 423, 208, - 422, 208, 421, 139, 209, 209, 209, 209, 209, 209, - 209, 277, 278, 279, 420, 419, 139, 141, 141, 141, - - 141, 141, 141, 141, 207, 207, 207, 207, 207, 207, - 207, 207, 207, 207, 207, 207, 207, 207, 209, 209, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 286, 287, 288, 293, 294, 295, 297, 298, - 299, 305, 306, 307, 387, 388, 389, 418, 417, 416, - 415, 414, 413, 412, 411, 410, 409, 390, 408, 391, - 79, 79, 405, 404, 403, 402, 401, 400, 399, 398, - 397, 396, 395, 394, 393, 392, 386, 385, 384, 383, - 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, - 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, - - 362, 361, 360, 359, 358, 357, 356, 355, 354, 353, - 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, - 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, - 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, - 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, - 312, 311, 310, 309, 308, 304, 303, 302, 301, 300, - 296, 292, 291, 290, 289, 285, 284, 283, 282, 281, - 280, 276, 275, 274, 273, 272, 268, 267, 266, 263, - 262, 261, 260, 259, 258, 257, 256, 255, 254, 253, - 252, 251, 250, 249, 248, 247, 246, 245, 241, 240, - - 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, - 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, - 219, 218, 215, 214, 213, 212, 211, 210, 205, 202, - 201, 200, 197, 196, 195, 194, 193, 192, 189, 188, - 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, - 175, 169, 168, 167, 166, 165, 164, 161, 160, 159, - 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, - 148, 147, 146, 145, 144, 143, 134, 118, 114, 109, - 102, 76, 71, 65, 59, 54, 442, 3, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442 + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 27, 28, 29, 26, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 26, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 26, 26, 26, 50, 51, + 52, 53, 55, 56, 57, 60, 62, 64, 64, 64, + 64, 64, 64, 64, 78, 79, 73, 144, 117, 63, + 61, 81, 118, 58, 66, 145, 67, 67, 67, 67, + + 67, 67, 68, 74, 83, 75, 76, 777, 86, 82, + 87, 115, 89, 69, 88, 97, 90, 98, 84, 85, + 70, 71, 91, 93, 116, 92, 99, 94, 109, 180, + 69, 110, 95, 119, 111, 112, 146, 161, 96, 113, + 181, 162, 114, 778, 70, 122, 120, 71, 66, 100, + 68, 68, 68, 68, 68, 68, 68, 101, 106, 102, + 123, 200, 103, 124, 205, 126, 107, 69, 104, 201, + 206, 779, 127, 128, 70, 133, 129, 108, 134, 229, + 230, 147, 130, 131, 69, 132, 135, 141, 137, 148, + 149, 142, 138, 136, 151, 152, 139, 231, 70, 140, + + 143, 153, 812, 260, 261, 232, 148, 149, 154, 780, + 154, 151, 152, 155, 155, 155, 155, 155, 155, 155, + 182, 220, 169, 247, 208, 153, 170, 171, 812, 213, + 222, 192, 781, 183, 193, 194, 221, 209, 195, 210, + 196, 233, 238, 223, 239, 214, 215, 247, 242, 234, + 242, 151, 152, 243, 243, 243, 243, 243, 243, 243, + 291, 292, 293, 782, 783, 244, 784, 244, 151, 152, + 245, 245, 245, 245, 245, 245, 245, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 254, 305, 323, 785, 786, 306, 330, 331, 332, + + 787, 324, 246, 788, 255, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 246, + 245, 245, 245, 245, 245, 245, 245, 341, 342, 343, + 149, 245, 245, 245, 245, 245, 245, 245, 353, 354, + 355, 361, 362, 363, 365, 366, 367, 149, 789, 152, + 376, 377, 378, 414, 415, 416, 434, 435, 436, 444, + 445, 446, 447, 448, 449, 790, 152, 791, 792, 437, + 438, 450, 451, 452, 491, 492, 493, 517, 518, 519, + 793, 794, 539, 541, 556, 557, 558, 494, 495, 629, + 520, 521, 540, 542, 587, 588, 589, 559, 560, 630, + + 561, 607, 608, 609, 659, 795, 796, 590, 591, 631, + 797, 660, 798, 661, 610, 611, 632, 679, 633, 634, + 799, 800, 801, 802, 680, 803, 681, 804, 805, 806, + 807, 808, 809, 810, 811, 80, 80, 80, 64, 150, + 156, 156, 776, 775, 774, 773, 772, 771, 770, 769, + 768, 767, 766, 765, 764, 763, 762, 761, 760, 759, + 758, 757, 756, 755, 754, 753, 752, 751, 750, 749, + 748, 747, 746, 745, 744, 743, 742, 741, 740, 739, + 738, 737, 736, 735, 734, 733, 732, 731, 730, 729, + 728, 727, 726, 725, 724, 723, 722, 721, 720, 719, + + 718, 717, 716, 715, 714, 713, 712, 711, 710, 709, + 708, 707, 706, 705, 704, 703, 702, 701, 700, 699, + 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, + 688, 687, 686, 685, 684, 683, 682, 678, 677, 676, + 675, 674, 673, 672, 671, 670, 669, 668, 667, 666, + 665, 664, 663, 662, 658, 657, 656, 655, 654, 653, + 652, 651, 650, 649, 648, 647, 646, 645, 644, 643, + 642, 641, 640, 639, 638, 637, 636, 635, 628, 627, + 626, 625, 624, 623, 622, 621, 620, 619, 618, 617, + 616, 615, 614, 613, 612, 606, 605, 604, 603, 602, + + 601, 600, 599, 598, 597, 596, 595, 594, 593, 592, + 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, + 576, 575, 574, 573, 572, 571, 570, 569, 568, 567, + 566, 565, 564, 563, 562, 555, 554, 553, 552, 551, + 550, 549, 548, 547, 546, 545, 544, 543, 538, 537, + 536, 535, 534, 533, 532, 531, 530, 529, 528, 527, + 526, 525, 524, 523, 522, 516, 515, 514, 513, 512, + 511, 510, 509, 508, 507, 506, 505, 504, 503, 502, + 501, 500, 499, 498, 497, 496, 490, 489, 488, 487, + 486, 485, 484, 483, 482, 481, 480, 479, 478, 477, + + 476, 475, 474, 473, 472, 471, 470, 469, 468, 467, + 466, 465, 464, 463, 462, 461, 460, 459, 458, 457, + 456, 455, 454, 453, 443, 442, 441, 440, 439, 433, + 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, + 422, 421, 420, 419, 418, 417, 413, 412, 411, 410, + 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, + 399, 398, 397, 396, 395, 394, 393, 392, 391, 390, + 389, 388, 387, 386, 385, 384, 383, 382, 381, 380, + 379, 375, 374, 373, 372, 371, 370, 369, 368, 364, + 360, 359, 358, 357, 356, 352, 351, 350, 349, 348, + + 347, 346, 345, 344, 340, 339, 338, 337, 336, 335, + 334, 333, 329, 328, 327, 326, 325, 322, 321, 320, + 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, + 309, 308, 307, 304, 303, 302, 301, 300, 299, 298, + 297, 296, 295, 294, 290, 289, 288, 287, 286, 285, + 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, + 274, 273, 272, 271, 270, 269, 268, 267, 266, 265, + 264, 263, 262, 259, 258, 257, 256, 253, 252, 251, + 250, 249, 248, 241, 240, 237, 236, 235, 228, 227, + 226, 225, 224, 219, 218, 217, 216, 212, 211, 207, + + 204, 203, 202, 199, 198, 197, 191, 190, 189, 188, + 187, 186, 185, 184, 179, 178, 177, 176, 175, 174, + 173, 172, 168, 167, 166, 165, 164, 163, 160, 159, + 158, 157, 125, 121, 105, 77, 72, 65, 59, 54, + 812, 3, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812 } ; -static yyconst flex_int16_t yy_chk[656] = +static yyconst flex_int16_t yy_chk[1015] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -679,76 +849,116 @@ static yyconst flex_int16_t yy_chk[656] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, 8, 9, - 13, 15, 16, 16, 16, 16, 16, 16, 16, 24, - 24, 30, 30, 40, 15, 13, 47, 40, 9, 18, - 47, 18, 18, 18, 18, 18, 18, 18, 19, 29, - - 19, 19, 19, 19, 19, 19, 19, 18, 22, 31, - 41, 31, 18, 29, 444, 31, 19, 133, 439, 133, - 18, 32, 34, 41, 34, 22, 33, 22, 22, 19, - 33, 32, 35, 34, 32, 33, 37, 18, 51, 38, - 35, 33, 35, 43, 37, 35, 38, 99, 438, 45, - 48, 35, 437, 38, 48, 37, 45, 45, 43, 46, - 99, 43, 46, 48, 109, 129, 45, 45, 198, 45, - 46, 436, 109, 129, 152, 152, 198, 46, 51, 64, - 64, 64, 64, 64, 64, 64, 66, 66, 66, 66, - 66, 66, 66, 435, 107, 64, 122, 107, 107, 401, - - 401, 107, 66, 107, 178, 178, 178, 434, 64, 432, - 430, 122, 429, 428, 67, 66, 67, 67, 67, 67, - 67, 67, 67, 68, 427, 68, 68, 68, 68, 68, - 68, 68, 67, 140, 140, 140, 140, 140, 140, 140, - 426, 68, 69, 424, 69, 67, 423, 69, 69, 69, - 69, 69, 69, 69, 68, 137, 422, 137, 421, 420, - 137, 137, 137, 137, 137, 137, 137, 138, 138, 138, - 138, 138, 138, 138, 202, 202, 202, 419, 418, 139, - 417, 139, 416, 138, 139, 139, 139, 139, 139, 139, - 139, 213, 213, 213, 414, 413, 138, 141, 141, 141, - - 141, 141, 141, 141, 206, 206, 206, 206, 206, 206, - 206, 207, 207, 207, 207, 207, 207, 207, 208, 208, - 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, - 209, 209, 221, 221, 221, 229, 229, 229, 233, 233, - 233, 239, 239, 239, 372, 372, 372, 412, 411, 410, - 409, 408, 407, 406, 405, 404, 403, 372, 402, 372, - 443, 443, 400, 391, 390, 389, 388, 387, 386, 384, - 383, 382, 379, 378, 376, 373, 371, 370, 369, 367, - 366, 365, 362, 361, 360, 359, 358, 357, 356, 355, - 349, 346, 343, 342, 341, 340, 339, 337, 335, 334, - - 333, 332, 330, 329, 327, 325, 324, 323, 322, 321, - 320, 319, 318, 316, 315, 314, 313, 312, 311, 310, - 309, 308, 304, 303, 300, 289, 285, 284, 283, 282, - 275, 274, 273, 268, 267, 266, 265, 264, 263, 260, - 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, - 249, 248, 247, 246, 245, 238, 237, 236, 235, 234, - 232, 228, 226, 225, 224, 220, 219, 218, 217, 216, - 215, 212, 210, 205, 204, 203, 201, 200, 199, 197, - 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, - 186, 185, 184, 183, 182, 181, 180, 179, 177, 176, - - 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, - 165, 163, 162, 161, 160, 159, 158, 157, 156, 155, - 154, 153, 151, 150, 149, 148, 147, 146, 134, 132, - 131, 130, 128, 127, 126, 125, 124, 123, 121, 120, - 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, - 108, 105, 104, 103, 102, 101, 100, 98, 97, 96, - 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, - 85, 84, 83, 82, 78, 74, 49, 44, 42, 39, - 36, 23, 20, 17, 12, 7, 3, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 8, 8, 9, 13, 15, 16, 16, 16, + 16, 16, 16, 16, 24, 24, 22, 49, 40, 15, + 13, 29, 40, 9, 18, 49, 18, 18, 18, 18, + + 18, 18, 18, 22, 30, 22, 22, 759, 31, 29, + 31, 39, 32, 18, 31, 34, 32, 34, 30, 30, + 18, 18, 32, 33, 39, 32, 34, 33, 38, 101, + 18, 38, 33, 41, 38, 38, 51, 85, 33, 38, + 101, 85, 38, 760, 18, 43, 41, 18, 19, 35, + 19, 19, 19, 19, 19, 19, 19, 35, 37, 35, + 43, 116, 35, 43, 120, 45, 37, 19, 35, 116, + 120, 761, 45, 45, 19, 46, 45, 37, 46, 137, + 137, 51, 45, 45, 19, 45, 46, 48, 47, 64, + 64, 48, 47, 46, 66, 66, 47, 138, 19, 47, + + 48, 67, 67, 171, 171, 138, 64, 64, 69, 762, + 69, 66, 66, 69, 69, 69, 69, 69, 69, 69, + 102, 130, 92, 156, 122, 67, 92, 92, 67, 125, + 131, 112, 763, 102, 112, 112, 130, 122, 112, 122, + 112, 139, 143, 131, 143, 125, 125, 156, 148, 139, + 148, 150, 150, 148, 148, 148, 148, 148, 148, 148, + 202, 202, 202, 766, 767, 151, 770, 151, 150, 150, + 151, 151, 151, 151, 151, 151, 151, 154, 154, 154, + 154, 154, 154, 154, 155, 155, 155, 155, 155, 155, + 155, 166, 214, 231, 771, 773, 214, 237, 237, 237, + + 774, 231, 155, 775, 166, 242, 242, 242, 242, 242, + 242, 242, 243, 243, 243, 243, 243, 243, 243, 155, + 244, 244, 244, 244, 244, 244, 244, 253, 253, 253, + 243, 245, 245, 245, 245, 245, 245, 245, 265, 265, + 265, 274, 274, 274, 278, 278, 278, 243, 777, 245, + 287, 287, 287, 328, 328, 328, 369, 369, 369, 380, + 380, 380, 381, 381, 381, 778, 245, 781, 782, 369, + 369, 382, 382, 382, 433, 433, 433, 476, 476, 476, + 783, 784, 496, 497, 513, 513, 513, 433, 433, 596, + 476, 476, 496, 497, 547, 547, 547, 513, 513, 596, + + 513, 570, 570, 570, 624, 785, 786, 547, 547, 597, + 788, 624, 789, 624, 570, 570, 597, 645, 597, 597, + 790, 791, 792, 793, 645, 795, 645, 796, 797, 799, + 803, 804, 805, 807, 808, 813, 813, 813, 814, 815, + 816, 816, 758, 757, 756, 755, 754, 753, 750, 749, + 748, 747, 746, 745, 744, 743, 742, 741, 738, 737, + 734, 733, 732, 731, 730, 729, 727, 726, 725, 724, + 723, 721, 719, 715, 714, 713, 712, 711, 709, 708, + 707, 706, 705, 704, 703, 702, 701, 700, 699, 698, + 697, 695, 694, 693, 692, 691, 690, 689, 688, 687, + + 685, 684, 683, 682, 681, 680, 679, 678, 677, 676, + 675, 674, 673, 672, 671, 670, 669, 668, 667, 666, + 665, 664, 663, 662, 661, 660, 659, 658, 656, 655, + 654, 653, 652, 651, 650, 648, 647, 644, 642, 641, + 640, 638, 637, 636, 635, 634, 633, 632, 631, 630, + 629, 628, 627, 626, 623, 622, 621, 620, 619, 618, + 616, 615, 614, 613, 611, 610, 609, 608, 607, 606, + 605, 604, 603, 602, 601, 600, 599, 598, 593, 591, + 590, 589, 588, 587, 583, 582, 581, 580, 579, 578, + 577, 576, 575, 573, 572, 568, 567, 565, 564, 562, + + 561, 560, 559, 558, 557, 556, 552, 551, 550, 548, + 546, 545, 544, 543, 542, 541, 540, 539, 538, 537, + 535, 534, 529, 528, 527, 526, 524, 523, 521, 520, + 519, 518, 517, 515, 514, 512, 511, 510, 509, 508, + 507, 506, 505, 503, 502, 501, 500, 499, 495, 494, + 493, 492, 491, 490, 487, 486, 485, 484, 483, 482, + 481, 480, 479, 478, 477, 475, 474, 471, 466, 464, + 463, 462, 460, 459, 456, 455, 454, 453, 442, 441, + 440, 438, 437, 436, 435, 434, 431, 429, 428, 427, + 425, 424, 423, 422, 420, 418, 417, 412, 411, 409, + + 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, + 397, 396, 395, 394, 393, 392, 391, 389, 388, 387, + 386, 385, 384, 383, 379, 375, 374, 373, 370, 368, + 358, 356, 352, 351, 350, 349, 347, 346, 344, 339, + 338, 337, 336, 335, 334, 329, 327, 326, 325, 324, + 323, 321, 320, 317, 316, 315, 314, 313, 312, 311, + 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, + 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, + 288, 286, 285, 284, 283, 282, 281, 280, 279, 277, + 273, 271, 270, 269, 268, 264, 263, 262, 261, 260, + + 259, 258, 257, 256, 252, 250, 249, 248, 241, 240, + 239, 238, 236, 235, 234, 233, 232, 230, 229, 228, + 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, + 217, 216, 215, 213, 212, 211, 210, 209, 208, 207, + 206, 205, 204, 203, 201, 200, 199, 198, 197, 196, + 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, + 185, 183, 182, 181, 180, 179, 178, 177, 176, 175, + 174, 173, 172, 170, 169, 168, 167, 165, 164, 163, + 162, 161, 159, 145, 144, 142, 141, 140, 136, 135, + 134, 133, 132, 129, 128, 127, 126, 124, 123, 121, + + 119, 118, 117, 115, 114, 113, 111, 110, 108, 107, + 106, 105, 104, 103, 100, 99, 98, 97, 96, 95, + 94, 93, 91, 90, 89, 88, 87, 86, 84, 83, + 79, 75, 44, 42, 36, 23, 20, 17, 12, 7, + 3, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[148] = +static yyconst flex_int32_t yy_rule_can_match_eol[238] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -757,7 +967,11 @@ static yyconst flex_int32_t yy_rule_can_match_eol[148] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, }; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -768,7 +982,7 @@ static yyconst flex_int32_t yy_rule_can_match_eol[148] = #define YY_RESTORE_YY_MORE_OFFSET /* // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -781,10 +995,11 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). */ -#include "compiler/glslang.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/glslang.h" +#include "compiler/translator/ParseContext.h" #include "compiler/preprocessor/Token.h" -#include "compiler/util.h" +#include "compiler/translator/util.h" +#include "compiler/translator/length_limits.h" #include "glslang_tab.h" /* windows only pragma */ @@ -802,8 +1017,13 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner); static int check_type(yyscan_t yyscanner); static int reserved_word(yyscan_t yyscanner); +static int ES2_reserved_ES3_keyword(TParseContext *context, int token); +static int ES2_keyword_ES3_reserved(TParseContext *context, int token); +static int ES2_ident_ES3_keyword(TParseContext *context, int token); +static int uint_constant(TParseContext *context); static int int_constant(yyscan_t yyscanner); static int float_constant(yyscan_t yyscanner); +static int floatsuffix_check(TParseContext* context); #define INITIAL 0 @@ -888,6 +1108,10 @@ int yyget_lineno (yyscan_t yyscanner ); void yyset_lineno (int line_number ,yyscan_t yyscanner ); +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + YYSTYPE * yyget_lval (yyscan_t yyscanner ); void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -936,7 +1160,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -947,7 +1171,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - yy_size_t n; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -1032,6 +1256,8 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + TParseContext* context = yyextra; + yylval = yylval_param; yylloc = yylloc_param; @@ -1087,13 +1313,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 443 ) + if ( yy_current_state >= 813 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 442 ); + while ( yy_current_state != 812 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1147,7 +1373,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -{ return ATTRIBUTE; } +{ return ES2_keyword_ES3_reserved(context, ATTRIBUTE); } YY_BREAK case 7: YY_RULE_SETUP @@ -1159,7 +1385,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -{ return VARYING; } +{ return ES2_keyword_ES3_reserved(context, VARYING); } YY_BREAK case 10: YY_RULE_SETUP @@ -1191,532 +1417,624 @@ YY_RULE_SETUP YY_BREAK case 17: YY_RULE_SETUP -{ return IN_QUAL; } +{ return ES2_reserved_ES3_keyword(context, SWITCH); } YY_BREAK case 18: YY_RULE_SETUP -{ return OUT_QUAL; } +{ return ES2_ident_ES3_keyword(context, CASE); } YY_BREAK case 19: YY_RULE_SETUP -{ return INOUT_QUAL; } +{ return ES2_reserved_ES3_keyword(context, DEFAULT); } YY_BREAK case 20: YY_RULE_SETUP -{ return FLOAT_TYPE; } +{ return ES2_ident_ES3_keyword(context, CENTROID); } YY_BREAK case 21: YY_RULE_SETUP -{ return INT_TYPE; } +{ return ES2_reserved_ES3_keyword(context, FLAT); } YY_BREAK case 22: YY_RULE_SETUP -{ return VOID_TYPE; } +{ return ES2_ident_ES3_keyword(context, SMOOTH); } YY_BREAK case 23: YY_RULE_SETUP -{ return BOOL_TYPE; } +{ return IN_QUAL; } YY_BREAK case 24: YY_RULE_SETUP -{ yylval->lex.b = true; return BOOLCONSTANT; } +{ return OUT_QUAL; } YY_BREAK case 25: YY_RULE_SETUP -{ yylval->lex.b = false; return BOOLCONSTANT; } +{ return INOUT_QUAL; } YY_BREAK case 26: YY_RULE_SETUP -{ return DISCARD; } +{ return FLOAT_TYPE; } YY_BREAK case 27: YY_RULE_SETUP -{ return RETURN; } +{ return INT_TYPE; } YY_BREAK case 28: YY_RULE_SETUP -{ return MATRIX2; } +{ return ES2_ident_ES3_keyword(context, UINT_TYPE); } YY_BREAK case 29: YY_RULE_SETUP -{ return MATRIX3; } +{ return VOID_TYPE; } YY_BREAK case 30: YY_RULE_SETUP -{ return MATRIX4; } +{ return BOOL_TYPE; } YY_BREAK case 31: YY_RULE_SETUP -{ return VEC2; } +{ yylval->lex.b = true; return BOOLCONSTANT; } YY_BREAK case 32: YY_RULE_SETUP -{ return VEC3; } +{ yylval->lex.b = false; return BOOLCONSTANT; } YY_BREAK case 33: YY_RULE_SETUP -{ return VEC4; } +{ return DISCARD; } YY_BREAK case 34: YY_RULE_SETUP -{ return IVEC2; } +{ return RETURN; } YY_BREAK case 35: YY_RULE_SETUP -{ return IVEC3; } +{ return MATRIX2; } YY_BREAK case 36: YY_RULE_SETUP -{ return IVEC4; } +{ return MATRIX3; } YY_BREAK case 37: YY_RULE_SETUP -{ return BVEC2; } +{ return MATRIX4; } YY_BREAK case 38: YY_RULE_SETUP -{ return BVEC3; } +{ return ES2_ident_ES3_keyword(context, MATRIX2); } YY_BREAK case 39: YY_RULE_SETUP -{ return BVEC4; } +{ return ES2_ident_ES3_keyword(context, MATRIX3); } YY_BREAK case 40: YY_RULE_SETUP -{ return SAMPLER2D; } +{ return ES2_ident_ES3_keyword(context, MATRIX4); } YY_BREAK case 41: YY_RULE_SETUP -{ return SAMPLERCUBE; } +{ return ES2_ident_ES3_keyword(context, MATRIX2x3); } YY_BREAK case 42: YY_RULE_SETUP -{ return SAMPLER_EXTERNAL_OES; } +{ return ES2_ident_ES3_keyword(context, MATRIX3x2); } YY_BREAK case 43: YY_RULE_SETUP -{ return SAMPLER2DRECT; } +{ return ES2_ident_ES3_keyword(context, MATRIX2x4); } YY_BREAK case 44: YY_RULE_SETUP -{ return STRUCT; } +{ return ES2_ident_ES3_keyword(context, MATRIX4x2); } YY_BREAK case 45: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, MATRIX3x4); } YY_BREAK case 46: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, MATRIX4x3); } YY_BREAK case 47: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return VEC2; } YY_BREAK case 48: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return VEC3; } YY_BREAK case 49: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return VEC4; } YY_BREAK case 50: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return IVEC2; } YY_BREAK case 51: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return IVEC3; } YY_BREAK case 52: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return IVEC4; } YY_BREAK case 53: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return BVEC2; } YY_BREAK case 54: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return BVEC3; } YY_BREAK case 55: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return BVEC4; } YY_BREAK case 56: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, UVEC2); } YY_BREAK case 57: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, UVEC3); } YY_BREAK case 58: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, UVEC4); } YY_BREAK case 59: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return SAMPLER2D; } YY_BREAK case 60: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return SAMPLERCUBE; } YY_BREAK case 61: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return SAMPLER_EXTERNAL_OES; } YY_BREAK case 62: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_reserved_ES3_keyword(context, SAMPLER3D); } YY_BREAK case 63: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); } YY_BREAK case 64: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return SAMPLER2DRECT; } YY_BREAK case 65: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, SAMPLER2DARRAY); } YY_BREAK case 66: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, ISAMPLER2D); } YY_BREAK case 67: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, ISAMPLER3D); } YY_BREAK case 68: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, ISAMPLERCUBE); } YY_BREAK case 69: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, ISAMPLER2DARRAY); } YY_BREAK case 70: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, USAMPLER2D); } YY_BREAK case 71: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, USAMPLER3D); } YY_BREAK case 72: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, USAMPLERCUBE); } YY_BREAK case 73: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, USAMPLER2DARRAY); } YY_BREAK case 74: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); } YY_BREAK case 75: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, SAMPLERCUBESHADOW); } YY_BREAK case 76: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, SAMPLER2DARRAYSHADOW); } YY_BREAK case 77: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return STRUCT; } YY_BREAK case 78: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ return ES2_ident_ES3_keyword(context, LAYOUT); } YY_BREAK +/* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */ case 79: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 80: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 81: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 82: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 83: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 84: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 85: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 86: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 87: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 88: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 89: -YY_RULE_SETUP -{ return reserved_word(yyscanner); } - YY_BREAK case 90: +case 91: +case 92: +case 93: +case 94: +case 95: +case 96: +case 97: +case 98: +case 99: +case 100: +case 101: +case 102: +case 103: +case 104: +case 105: +case 106: +case 107: +case 108: +case 109: +case 110: +case 111: +case 112: +case 113: +case 114: +case 115: +case 116: +case 117: +case 118: +case 119: +case 120: +case 121: +case 122: +case 123: +case 124: +case 125: +case 126: +case 127: +case 128: +case 129: +case 130: +case 131: +case 132: +case 133: +case 134: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ + if (context->shaderVersion < 300) { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + return reserved_word(yyscanner); +} YY_BREAK -case 91: +/* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */ +case 135: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ + if (context->shaderVersion >= 300) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + + return reserved_word(yyscanner); +} YY_BREAK -case 92: +/* Reserved keywords */ +case 136: +case 137: +case 138: +case 139: +case 140: +case 141: +case 142: +case 143: +case 144: +case 145: +case 146: +case 147: +case 148: +case 149: +case 150: +case 151: +case 152: +case 153: +case 154: +case 155: +case 156: +case 157: +case 158: +case 159: +case 160: +case 161: +case 162: +case 163: +case 164: +case 165: +case 166: +case 167: +case 168: +case 169: +case 170: +case 171: +case 172: +case 173: +case 174: +case 175: +case 176: YY_RULE_SETUP { return reserved_word(yyscanner); } YY_BREAK -case 93: +case 177: YY_RULE_SETUP { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); } YY_BREAK -case 94: +case 178: YY_RULE_SETUP { return int_constant(yyscanner); } YY_BREAK -case 95: +case 179: YY_RULE_SETUP { return int_constant(yyscanner); } YY_BREAK -case 96: +case 180: YY_RULE_SETUP { return int_constant(yyscanner); } YY_BREAK -case 97: +case 181: +YY_RULE_SETUP +{ return uint_constant(context); } + YY_BREAK +case 182: +YY_RULE_SETUP +{ return uint_constant(context); } + YY_BREAK +case 183: +YY_RULE_SETUP +{ return uint_constant(context); } + YY_BREAK +case 184: YY_RULE_SETUP { return float_constant(yyscanner); } YY_BREAK -case 98: +case 185: YY_RULE_SETUP { return float_constant(yyscanner); } YY_BREAK -case 99: +case 186: YY_RULE_SETUP { return float_constant(yyscanner); } YY_BREAK -case 100: +case 187: +YY_RULE_SETUP +{ return floatsuffix_check(context); } + YY_BREAK +case 188: +YY_RULE_SETUP +{ return floatsuffix_check(context); } + YY_BREAK +case 189: +YY_RULE_SETUP +{ return floatsuffix_check(context); } + YY_BREAK +case 190: YY_RULE_SETUP { return ADD_ASSIGN; } YY_BREAK -case 101: +case 191: YY_RULE_SETUP { return SUB_ASSIGN; } YY_BREAK -case 102: +case 192: YY_RULE_SETUP { return MUL_ASSIGN; } YY_BREAK -case 103: +case 193: YY_RULE_SETUP { return DIV_ASSIGN; } YY_BREAK -case 104: +case 194: YY_RULE_SETUP { return MOD_ASSIGN; } YY_BREAK -case 105: +case 195: YY_RULE_SETUP { return LEFT_ASSIGN; } YY_BREAK -case 106: +case 196: YY_RULE_SETUP { return RIGHT_ASSIGN; } YY_BREAK -case 107: +case 197: YY_RULE_SETUP { return AND_ASSIGN; } YY_BREAK -case 108: +case 198: YY_RULE_SETUP { return XOR_ASSIGN; } YY_BREAK -case 109: +case 199: YY_RULE_SETUP { return OR_ASSIGN; } YY_BREAK -case 110: +case 200: YY_RULE_SETUP { return INC_OP; } YY_BREAK -case 111: +case 201: YY_RULE_SETUP { return DEC_OP; } YY_BREAK -case 112: +case 202: YY_RULE_SETUP { return AND_OP; } YY_BREAK -case 113: +case 203: YY_RULE_SETUP { return OR_OP; } YY_BREAK -case 114: +case 204: YY_RULE_SETUP { return XOR_OP; } YY_BREAK -case 115: +case 205: YY_RULE_SETUP { return LE_OP; } YY_BREAK -case 116: +case 206: YY_RULE_SETUP { return GE_OP; } YY_BREAK -case 117: +case 207: YY_RULE_SETUP { return EQ_OP; } YY_BREAK -case 118: +case 208: YY_RULE_SETUP { return NE_OP; } YY_BREAK -case 119: +case 209: YY_RULE_SETUP { return LEFT_OP; } YY_BREAK -case 120: +case 210: YY_RULE_SETUP { return RIGHT_OP; } YY_BREAK -case 121: +case 211: YY_RULE_SETUP { return SEMICOLON; } YY_BREAK -case 122: +case 212: YY_RULE_SETUP { return LEFT_BRACE; } YY_BREAK -case 123: +case 213: YY_RULE_SETUP { return RIGHT_BRACE; } YY_BREAK -case 124: +case 214: YY_RULE_SETUP { return COMMA; } YY_BREAK -case 125: +case 215: YY_RULE_SETUP { return COLON; } YY_BREAK -case 126: +case 216: YY_RULE_SETUP { return EQUAL; } YY_BREAK -case 127: +case 217: YY_RULE_SETUP { return LEFT_PAREN; } YY_BREAK -case 128: +case 218: YY_RULE_SETUP { return RIGHT_PAREN; } YY_BREAK -case 129: +case 219: YY_RULE_SETUP { return LEFT_BRACKET; } YY_BREAK -case 130: +case 220: YY_RULE_SETUP { return RIGHT_BRACKET; } YY_BREAK -case 131: +case 221: YY_RULE_SETUP { return DOT; } YY_BREAK -case 132: +case 222: YY_RULE_SETUP { return BANG; } YY_BREAK -case 133: +case 223: YY_RULE_SETUP { return DASH; } YY_BREAK -case 134: +case 224: YY_RULE_SETUP { return TILDE; } YY_BREAK -case 135: +case 225: YY_RULE_SETUP { return PLUS; } YY_BREAK -case 136: +case 226: YY_RULE_SETUP { return STAR; } YY_BREAK -case 137: +case 227: YY_RULE_SETUP { return SLASH; } YY_BREAK -case 138: +case 228: YY_RULE_SETUP { return PERCENT; } YY_BREAK -case 139: +case 229: YY_RULE_SETUP { return LEFT_ANGLE; } YY_BREAK -case 140: +case 230: YY_RULE_SETUP { return RIGHT_ANGLE; } YY_BREAK -case 141: +case 231: YY_RULE_SETUP { return VERTICAL_BAR; } YY_BREAK -case 142: +case 232: YY_RULE_SETUP { return CARET; } YY_BREAK -case 143: +case 233: YY_RULE_SETUP { return AMPERSAND; } YY_BREAK -case 144: +case 234: YY_RULE_SETUP { return QUESTION; } YY_BREAK -case 145: -/* rule 145 can match eol */ +case 235: +/* rule 235 can match eol */ YY_RULE_SETUP { } YY_BREAK case YY_STATE_EOF(INITIAL): { yyterminate(); } YY_BREAK -case 146: +case 236: YY_RULE_SETUP { assert(false); return 0; } YY_BREAK -case 147: +case 237: YY_RULE_SETUP ECHO; YY_BREAK @@ -1912,7 +2230,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); @@ -2012,7 +2330,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 443 ) + if ( yy_current_state >= 813 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2041,12 +2359,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 443 ) + if ( yy_current_state >= 813 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 442); + yy_is_jam = (yy_current_state == 812); + (void)yyg; return yy_is_jam ? 0 : yy_current_state; } @@ -2455,8 +2774,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ @@ -2464,7 +2783,8 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len { YY_BUFFER_STATE b; char *buf; - yy_size_t n, i; + yy_size_t n; + yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2610,7 +2930,7 @@ void yyset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); + YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = line_number; } @@ -2625,7 +2945,7 @@ void yyset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_column called with no buffer" , yyscanner); + YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = column_no; } @@ -2881,11 +3201,12 @@ int check_type(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; int token = IDENTIFIER; - TSymbol* symbol = yyextra->symbolTable.find(yytext); + TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion); if (symbol && symbol->isVariable()) { TVariable* variable = static_cast<TVariable*>(symbol); - if (variable->isUserType()) + if (variable->isUserType()) { token = TYPE_NAME; + } } yylval->lex.symbol = symbol; return token; @@ -2899,6 +3220,80 @@ int reserved_word(yyscan_t yyscanner) { return 0; } +int ES2_reserved_ES3_keyword(TParseContext *context, int token) +{ + yyscan_t yyscanner = (yyscan_t) context->scanner; + + if (context->shaderVersion < 300) + { + return reserved_word(yyscanner); + } + + return token; +} + +int ES2_keyword_ES3_reserved(TParseContext *context, int token) +{ + yyscan_t yyscanner = (yyscan_t) context->scanner; + + if (context->shaderVersion >= 300) + { + return reserved_word(yyscanner); + } + + return token; +} + +int ES2_ident_ES3_keyword(TParseContext *context, int token) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->scanner; + + // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name + if (context->shaderVersion < 300) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + + return token; +} + +int uint_constant(TParseContext *context) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->scanner; + + if (context->shaderVersion < 300) + { + context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); + context->recover(); + return 0; + } + + if (!atoi_clamp(yytext, &(yylval->lex.i))) + yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + + return UINTCONSTANT; +} + +int floatsuffix_check(TParseContext* context) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + + if (context->shaderVersion < 300) + { + context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); + context->recover(); + return 0; + } + + if (!atof_clamp(yytext, &(yylval->lex.f))) + yyextra->warning(*yylloc, "Float overflow", yytext, ""); + + return(FLOATCONSTANT); +} + void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) { context->error(*lloc, reason, yyget_text(context->scanner)); context->recover(); @@ -2948,7 +3343,6 @@ int glslang_scan(size_t count, const char* const string[], const int length[], // Initialize preprocessor. if (!context->preprocessor.init(count, string, length)) return 1; - context->preprocessor.setMaxTokenLength(SH_MAX_TOKEN_LENGTH); // Define extension macros. const TExtensionBehavior& extBehavior = context->extensionBehavior(); @@ -2959,6 +3353,8 @@ int glslang_scan(size_t count, const char* const string[], const int length[], if (context->fragmentPrecisionHigh) context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); + context->preprocessor.setMaxTokenSize(GetGlobalMaxTokenSize(context->shaderSpec)); + return 0; } diff --git a/chromium/third_party/angle/src/compiler/glslang_tab.cpp b/chromium/third_party/angle/src/compiler/translator/glslang_tab.cpp index 1f2e89039ba..63ec8c7534f 100644 --- a/chromium/third_party/angle/src/compiler/glslang_tab.cpp +++ b/chromium/third_party/angle/src/compiler/translator/glslang_tab.cpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.7. */ +/* A Bison parser, made by GNU Bison 2.7.1. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.7" +#define YYBISON_VERSION "2.7.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -65,7 +65,7 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -84,8 +84,8 @@ #pragma warning(disable: 4701) #endif -#include "compiler/SymbolTable.h" -#include "compiler/ParseContext.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/ParseContext.h" #include "GLSLANG/ShaderLang.h" #define YYENABLE_NLS 0 @@ -94,6 +94,7 @@ + # ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULL nullptr @@ -126,7 +127,6 @@ extern int yydebug; #define YYLTYPE TSourceLoc #define YYLTYPE_IS_DECLARED 1 -#define SH_MAX_TOKEN_LENGTH 256 // WebGL spec. @@ -147,88 +147,121 @@ extern int yydebug; BOOL_TYPE = 265, FLOAT_TYPE = 266, INT_TYPE = 267, - BREAK = 268, - CONTINUE = 269, - DO = 270, - ELSE = 271, - FOR = 272, - IF = 273, - DISCARD = 274, - RETURN = 275, - BVEC2 = 276, - BVEC3 = 277, - BVEC4 = 278, - IVEC2 = 279, - IVEC3 = 280, - IVEC4 = 281, - VEC2 = 282, - VEC3 = 283, - VEC4 = 284, - MATRIX2 = 285, - MATRIX3 = 286, - MATRIX4 = 287, - IN_QUAL = 288, - OUT_QUAL = 289, - INOUT_QUAL = 290, - UNIFORM = 291, - VARYING = 292, - STRUCT = 293, - VOID_TYPE = 294, - WHILE = 295, - SAMPLER2D = 296, - SAMPLERCUBE = 297, - SAMPLER_EXTERNAL_OES = 298, - SAMPLER2DRECT = 299, - IDENTIFIER = 300, - TYPE_NAME = 301, - FLOATCONSTANT = 302, - INTCONSTANT = 303, - BOOLCONSTANT = 304, - LEFT_OP = 305, - RIGHT_OP = 306, - INC_OP = 307, - DEC_OP = 308, - LE_OP = 309, - GE_OP = 310, - EQ_OP = 311, - NE_OP = 312, - AND_OP = 313, - OR_OP = 314, - XOR_OP = 315, - MUL_ASSIGN = 316, - DIV_ASSIGN = 317, - ADD_ASSIGN = 318, - MOD_ASSIGN = 319, - LEFT_ASSIGN = 320, - RIGHT_ASSIGN = 321, - AND_ASSIGN = 322, - XOR_ASSIGN = 323, - OR_ASSIGN = 324, - SUB_ASSIGN = 325, - LEFT_PAREN = 326, - RIGHT_PAREN = 327, - LEFT_BRACKET = 328, - RIGHT_BRACKET = 329, - LEFT_BRACE = 330, - RIGHT_BRACE = 331, - DOT = 332, - COMMA = 333, - COLON = 334, - EQUAL = 335, - SEMICOLON = 336, - BANG = 337, - DASH = 338, - TILDE = 339, - PLUS = 340, - STAR = 341, - SLASH = 342, - PERCENT = 343, - LEFT_ANGLE = 344, - RIGHT_ANGLE = 345, - VERTICAL_BAR = 346, - CARET = 347, - AMPERSAND = 348, - QUESTION = 349 + UINT_TYPE = 268, + BREAK = 269, + CONTINUE = 270, + DO = 271, + ELSE = 272, + FOR = 273, + IF = 274, + DISCARD = 275, + RETURN = 276, + SWITCH = 277, + CASE = 278, + DEFAULT = 279, + BVEC2 = 280, + BVEC3 = 281, + BVEC4 = 282, + IVEC2 = 283, + IVEC3 = 284, + IVEC4 = 285, + VEC2 = 286, + VEC3 = 287, + VEC4 = 288, + UVEC2 = 289, + UVEC3 = 290, + UVEC4 = 291, + MATRIX2 = 292, + MATRIX3 = 293, + MATRIX4 = 294, + IN_QUAL = 295, + OUT_QUAL = 296, + INOUT_QUAL = 297, + UNIFORM = 298, + VARYING = 299, + MATRIX2x3 = 300, + MATRIX3x2 = 301, + MATRIX2x4 = 302, + MATRIX4x2 = 303, + MATRIX3x4 = 304, + MATRIX4x3 = 305, + CENTROID = 306, + FLAT = 307, + SMOOTH = 308, + STRUCT = 309, + VOID_TYPE = 310, + WHILE = 311, + SAMPLER2D = 312, + SAMPLERCUBE = 313, + SAMPLER_EXTERNAL_OES = 314, + SAMPLER2DRECT = 315, + SAMPLER2DARRAY = 316, + ISAMPLER2D = 317, + ISAMPLER3D = 318, + ISAMPLERCUBE = 319, + ISAMPLER2DARRAY = 320, + USAMPLER2D = 321, + USAMPLER3D = 322, + USAMPLERCUBE = 323, + USAMPLER2DARRAY = 324, + SAMPLER3D = 325, + SAMPLER3DRECT = 326, + SAMPLER2DSHADOW = 327, + SAMPLERCUBESHADOW = 328, + SAMPLER2DARRAYSHADOW = 329, + LAYOUT = 330, + IDENTIFIER = 331, + TYPE_NAME = 332, + FLOATCONSTANT = 333, + INTCONSTANT = 334, + UINTCONSTANT = 335, + BOOLCONSTANT = 336, + FIELD_SELECTION = 337, + LEFT_OP = 338, + RIGHT_OP = 339, + INC_OP = 340, + DEC_OP = 341, + LE_OP = 342, + GE_OP = 343, + EQ_OP = 344, + NE_OP = 345, + AND_OP = 346, + OR_OP = 347, + XOR_OP = 348, + MUL_ASSIGN = 349, + DIV_ASSIGN = 350, + ADD_ASSIGN = 351, + MOD_ASSIGN = 352, + LEFT_ASSIGN = 353, + RIGHT_ASSIGN = 354, + AND_ASSIGN = 355, + XOR_ASSIGN = 356, + OR_ASSIGN = 357, + SUB_ASSIGN = 358, + LEFT_PAREN = 359, + RIGHT_PAREN = 360, + LEFT_BRACKET = 361, + RIGHT_BRACKET = 362, + LEFT_BRACE = 363, + RIGHT_BRACE = 364, + DOT = 365, + COMMA = 366, + COLON = 367, + EQUAL = 368, + SEMICOLON = 369, + BANG = 370, + DASH = 371, + TILDE = 372, + PLUS = 373, + STAR = 374, + SLASH = 375, + PERCENT = 376, + LEFT_ANGLE = 377, + RIGHT_ANGLE = 378, + VERTICAL_BAR = 379, + CARET = 380, + AMPERSAND = 381, + QUESTION = 382 }; #endif @@ -243,6 +276,7 @@ typedef union YYSTYPE TString *string; float f; int i; + unsigned int u; bool b; }; TSymbol* symbol; @@ -258,6 +292,7 @@ typedef union YYSTYPE union { TPublicType type; TPrecision precision; + TLayoutQualifier layoutQualifier; TQualifier qualifier; TFunction* function; TParameter param; @@ -340,6 +375,20 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) } \ } +#define ES2_ONLY(S, L) { \ + if (context->shaderVersion != 100) { \ + context->error(L, " supported in GLSL ES 1.00 only ", S); \ + context->recover(); \ + } \ +} + +#define ES3_ONLY(TOKEN, LINE, REASON) { \ + if (context->shaderVersion != 300) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ + context->recover(); \ + } \ +} + #ifdef short @@ -401,6 +450,14 @@ typedef short int yytype_int16; # endif #endif +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ +# endif +#endif + /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -408,6 +465,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif + /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(N) (N) @@ -560,22 +618,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 74 +#define YYFINAL 114 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1490 +#define YYLAST 2375 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 95 +#define YYNTOKENS 128 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 84 +#define YYNNTS 91 /* YYNRULES -- Number of rules. */ -#define YYNRULES 202 +#define YYNRULES 250 /* YYNRULES -- Number of states. */ -#define YYNSTATES 307 +#define YYNSTATES 373 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 349 +#define YYMAXUTOK 382 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -617,7 +675,11 @@ static const yytype_uint8 yytranslate[] = 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94 + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127 }; #if YYDEBUG @@ -626,115 +688,138 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint16 yyprhs[] = { 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, - 21, 23, 28, 30, 34, 37, 40, 42, 44, 46, - 50, 53, 56, 59, 61, 64, 68, 71, 73, 75, - 77, 80, 83, 86, 88, 90, 92, 94, 98, 102, - 104, 108, 112, 114, 116, 120, 124, 128, 132, 134, - 138, 142, 144, 146, 148, 150, 154, 156, 160, 162, - 166, 168, 174, 176, 180, 182, 184, 186, 188, 190, - 192, 196, 198, 201, 204, 209, 212, 214, 216, 219, - 223, 227, 230, 236, 240, 243, 247, 250, 251, 253, - 255, 257, 259, 261, 265, 271, 278, 284, 286, 289, - 294, 300, 305, 308, 310, 313, 315, 317, 319, 322, - 324, 326, 329, 331, 333, 335, 337, 342, 344, 346, - 348, 350, 352, 354, 356, 358, 360, 362, 364, 366, - 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, - 387, 394, 395, 401, 403, 406, 410, 412, 416, 418, - 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, - 444, 445, 446, 452, 454, 456, 457, 460, 461, 464, - 467, 471, 473, 476, 478, 481, 487, 491, 493, 495, - 500, 501, 508, 509, 518, 519, 527, 529, 531, 533, - 534, 537, 541, 544, 547, 550, 554, 557, 559, 562, - 564, 566, 567 + 19, 23, 25, 30, 32, 36, 39, 42, 44, 46, + 48, 52, 55, 58, 61, 63, 66, 70, 73, 75, + 77, 79, 82, 85, 88, 90, 92, 94, 96, 100, + 104, 106, 110, 114, 116, 118, 122, 126, 130, 134, + 136, 140, 144, 146, 148, 150, 152, 156, 158, 162, + 164, 168, 170, 176, 178, 182, 184, 186, 188, 190, + 192, 194, 198, 200, 203, 206, 209, 214, 220, 227, + 237, 240, 243, 245, 247, 250, 254, 258, 261, 267, + 271, 274, 278, 281, 282, 284, 286, 288, 290, 292, + 296, 302, 309, 315, 317, 320, 325, 331, 336, 339, + 341, 344, 346, 348, 350, 352, 354, 357, 359, 362, + 364, 366, 369, 371, 373, 375, 378, 381, 383, 385, + 388, 390, 392, 394, 399, 401, 405, 407, 411, 415, + 417, 422, 424, 426, 428, 430, 432, 434, 436, 438, + 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, + 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, + 480, 482, 484, 486, 488, 490, 492, 494, 496, 498, + 500, 502, 504, 506, 508, 510, 512, 513, 520, 521, + 527, 529, 532, 536, 541, 543, 547, 549, 554, 556, + 558, 560, 562, 564, 566, 568, 570, 572, 575, 576, + 577, 583, 585, 587, 588, 591, 592, 595, 598, 602, + 604, 607, 609, 612, 618, 622, 624, 626, 631, 632, + 639, 640, 649, 650, 658, 660, 662, 664, 665, 668, + 672, 675, 678, 681, 685, 688, 690, 693, 695, 697, + 698 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 175, 0, -1, 45, -1, 46, -1, 45, -1, 97, - -1, 48, -1, 47, -1, 49, -1, 71, 124, 72, - -1, 98, -1, 99, 73, 100, 74, -1, 101, -1, - 99, 77, 96, -1, 99, 52, -1, 99, 53, -1, - 124, -1, 102, -1, 103, -1, 99, 77, 103, -1, - 105, 72, -1, 104, 72, -1, 106, 39, -1, 106, - -1, 106, 122, -1, 105, 78, 122, -1, 107, 71, - -1, 142, -1, 45, -1, 99, -1, 52, 108, -1, - 53, 108, -1, 109, 108, -1, 85, -1, 83, -1, - 82, -1, 108, -1, 110, 86, 108, -1, 110, 87, - 108, -1, 110, -1, 111, 85, 110, -1, 111, 83, - 110, -1, 111, -1, 112, -1, 113, 89, 112, -1, - 113, 90, 112, -1, 113, 54, 112, -1, 113, 55, - 112, -1, 113, -1, 114, 56, 113, -1, 114, 57, - 113, -1, 114, -1, 115, -1, 116, -1, 117, -1, - 118, 58, 117, -1, 118, -1, 119, 60, 118, -1, - 119, -1, 120, 59, 119, -1, 120, -1, 120, 94, - 124, 79, 122, -1, 121, -1, 108, 123, 122, -1, - 80, -1, 61, -1, 62, -1, 63, -1, 70, -1, - 122, -1, 124, 78, 122, -1, 121, -1, 127, 81, - -1, 135, 81, -1, 7, 140, 141, 81, -1, 128, - 72, -1, 130, -1, 129, -1, 130, 132, -1, 129, - 78, 132, -1, 137, 45, 71, -1, 139, 96, -1, - 139, 96, 73, 125, 74, -1, 138, 133, 131, -1, - 133, 131, -1, 138, 133, 134, -1, 133, 134, -1, - -1, 33, -1, 34, -1, 35, -1, 139, -1, 136, - -1, 135, 78, 96, -1, 135, 78, 96, 73, 74, - -1, 135, 78, 96, 73, 125, 74, -1, 135, 78, - 96, 80, 150, -1, 137, -1, 137, 96, -1, 137, - 96, 73, 74, -1, 137, 96, 73, 125, 74, -1, - 137, 96, 80, 150, -1, 3, 45, -1, 139, -1, - 138, 139, -1, 9, -1, 8, -1, 37, -1, 3, - 37, -1, 36, -1, 141, -1, 140, 141, -1, 4, - -1, 5, -1, 6, -1, 142, -1, 142, 73, 125, - 74, -1, 39, -1, 11, -1, 12, -1, 10, -1, - 27, -1, 28, -1, 29, -1, 21, -1, 22, -1, - 23, -1, 24, -1, 25, -1, 26, -1, 30, -1, - 31, -1, 32, -1, 41, -1, 42, -1, 43, -1, - 44, -1, 143, -1, 46, -1, -1, 38, 96, 75, - 144, 146, 76, -1, -1, 38, 75, 145, 146, 76, - -1, 147, -1, 146, 147, -1, 139, 148, 81, -1, - 149, -1, 148, 78, 149, -1, 96, -1, 96, 73, - 125, 74, -1, 122, -1, 126, -1, 154, -1, 153, - -1, 151, -1, 163, -1, 164, -1, 167, -1, 174, - -1, 75, 76, -1, -1, -1, 75, 155, 162, 156, - 76, -1, 161, -1, 153, -1, -1, 159, 161, -1, - -1, 160, 153, -1, 75, 76, -1, 75, 162, 76, - -1, 152, -1, 162, 152, -1, 81, -1, 124, 81, - -1, 18, 71, 124, 72, 165, -1, 158, 16, 158, - -1, 158, -1, 124, -1, 137, 96, 80, 150, -1, - -1, 40, 71, 168, 166, 72, 157, -1, -1, 15, - 169, 158, 40, 71, 124, 72, 81, -1, -1, 17, - 71, 170, 171, 173, 72, 157, -1, 163, -1, 151, - -1, 166, -1, -1, 172, 81, -1, 172, 81, 124, - -1, 14, 81, -1, 13, 81, -1, 20, 81, -1, - 20, 124, 81, -1, 19, 81, -1, 176, -1, 175, - 176, -1, 177, -1, 126, -1, -1, 127, 178, 161, - -1 + 215, 0, -1, 76, -1, 77, -1, 76, -1, 130, + -1, 79, -1, 80, -1, 78, -1, 81, -1, 104, + 157, 105, -1, 131, -1, 132, 106, 133, 107, -1, + 134, -1, 132, 110, 129, -1, 132, 85, -1, 132, + 86, -1, 157, -1, 135, -1, 136, -1, 132, 110, + 136, -1, 138, 105, -1, 137, 105, -1, 139, 55, + -1, 139, -1, 139, 155, -1, 138, 111, 155, -1, + 140, 104, -1, 182, -1, 76, -1, 132, -1, 85, + 141, -1, 86, 141, -1, 142, 141, -1, 118, -1, + 116, -1, 115, -1, 141, -1, 143, 119, 141, -1, + 143, 120, 141, -1, 143, -1, 144, 118, 143, -1, + 144, 116, 143, -1, 144, -1, 145, -1, 146, 122, + 145, -1, 146, 123, 145, -1, 146, 87, 145, -1, + 146, 88, 145, -1, 146, -1, 147, 89, 146, -1, + 147, 90, 146, -1, 147, -1, 148, -1, 149, -1, + 150, -1, 151, 91, 150, -1, 151, -1, 152, 93, + 151, -1, 152, -1, 153, 92, 152, -1, 153, -1, + 153, 127, 157, 112, 155, -1, 154, -1, 141, 156, + 155, -1, 113, -1, 94, -1, 95, -1, 96, -1, + 103, -1, 155, -1, 157, 111, 155, -1, 154, -1, + 76, 108, -1, 161, 114, -1, 169, 114, -1, 7, + 177, 181, 114, -1, 174, 159, 186, 109, 114, -1, + 174, 159, 186, 109, 76, 114, -1, 174, 159, 186, + 109, 76, 106, 158, 107, 114, -1, 174, 114, -1, + 162, 105, -1, 164, -1, 163, -1, 164, 166, -1, + 163, 111, 166, -1, 171, 76, 104, -1, 176, 129, + -1, 176, 129, 106, 158, 107, -1, 173, 167, 165, + -1, 167, 165, -1, 173, 167, 168, -1, 167, 168, + -1, -1, 40, -1, 41, -1, 42, -1, 176, -1, + 170, -1, 169, 111, 129, -1, 169, 111, 129, 106, + 107, -1, 169, 111, 129, 106, 158, 107, -1, 169, + 111, 129, 113, 190, -1, 171, -1, 171, 129, -1, + 171, 129, 106, 107, -1, 171, 129, 106, 158, 107, + -1, 171, 129, 113, 190, -1, 3, 76, -1, 176, + -1, 174, 176, -1, 53, -1, 52, -1, 9, -1, + 8, -1, 44, -1, 3, 44, -1, 175, -1, 172, + 175, -1, 172, -1, 178, -1, 178, 175, -1, 9, + -1, 40, -1, 41, -1, 51, 40, -1, 51, 41, + -1, 43, -1, 181, -1, 177, 181, -1, 4, -1, + 5, -1, 6, -1, 75, 104, 179, 105, -1, 180, + -1, 179, 111, 180, -1, 76, -1, 76, 113, 79, + -1, 76, 113, 80, -1, 182, -1, 182, 106, 158, + 107, -1, 55, -1, 11, -1, 12, -1, 13, -1, + 10, -1, 31, -1, 32, -1, 33, -1, 25, -1, + 26, -1, 27, -1, 28, -1, 29, -1, 30, -1, + 34, -1, 35, -1, 36, -1, 37, -1, 38, -1, + 39, -1, 45, -1, 46, -1, 47, -1, 48, -1, + 49, -1, 50, -1, 57, -1, 70, -1, 58, -1, + 61, -1, 62, -1, 63, -1, 64, -1, 65, -1, + 66, -1, 67, -1, 68, -1, 69, -1, 72, -1, + 73, -1, 74, -1, 59, -1, 60, -1, 183, -1, + 77, -1, -1, 54, 129, 108, 184, 186, 109, -1, + -1, 54, 108, 185, 186, 109, -1, 187, -1, 186, + 187, -1, 176, 188, 114, -1, 174, 176, 188, 114, + -1, 189, -1, 188, 111, 189, -1, 129, -1, 129, + 106, 158, 107, -1, 155, -1, 160, -1, 194, -1, + 193, -1, 191, -1, 203, -1, 204, -1, 207, -1, + 214, -1, 108, 109, -1, -1, -1, 108, 195, 202, + 196, 109, -1, 201, -1, 193, -1, -1, 199, 201, + -1, -1, 200, 193, -1, 108, 109, -1, 108, 202, + 109, -1, 192, -1, 202, 192, -1, 114, -1, 157, + 114, -1, 19, 104, 157, 105, 205, -1, 198, 17, + 198, -1, 198, -1, 157, -1, 171, 129, 113, 190, + -1, -1, 56, 104, 208, 206, 105, 197, -1, -1, + 16, 209, 198, 56, 104, 157, 105, 114, -1, -1, + 18, 104, 210, 211, 213, 105, 197, -1, 203, -1, + 191, -1, 206, -1, -1, 212, 114, -1, 212, 114, + 157, -1, 15, 114, -1, 14, 114, -1, 21, 114, + -1, 21, 157, 114, -1, 20, 114, -1, 216, -1, + 215, 216, -1, 217, -1, 160, -1, -1, 161, 218, + 201, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 180, 180, 181, 184, 227, 230, 243, 248, 253, - 259, 262, 265, 268, 363, 373, 386, 394, 494, 497, - 505, 508, 514, 518, 525, 531, 540, 548, 603, 613, - 616, 626, 636, 657, 658, 659, 664, 665, 673, 684, - 685, 693, 704, 708, 709, 719, 729, 739, 752, 753, - 763, 776, 780, 784, 788, 789, 802, 803, 816, 817, - 830, 831, 848, 849, 862, 863, 864, 865, 866, 870, - 873, 884, 892, 919, 924, 938, 993, 996, 1003, 1011, - 1032, 1053, 1063, 1091, 1096, 1106, 1111, 1121, 1124, 1127, - 1130, 1136, 1143, 1146, 1168, 1186, 1210, 1233, 1237, 1255, - 1263, 1295, 1315, 1336, 1345, 1368, 1371, 1377, 1385, 1393, - 1401, 1411, 1418, 1421, 1424, 1430, 1433, 1448, 1452, 1456, - 1460, 1464, 1469, 1474, 1479, 1484, 1489, 1494, 1499, 1504, - 1509, 1514, 1519, 1524, 1528, 1532, 1540, 1548, 1552, 1565, - 1565, 1579, 1579, 1588, 1591, 1607, 1640, 1644, 1650, 1657, - 1672, 1676, 1680, 1681, 1687, 1688, 1689, 1690, 1691, 1695, - 1696, 1696, 1696, 1706, 1707, 1711, 1711, 1712, 1712, 1717, - 1720, 1730, 1733, 1739, 1740, 1744, 1752, 1756, 1766, 1771, - 1788, 1788, 1793, 1793, 1800, 1800, 1808, 1811, 1817, 1820, - 1826, 1830, 1837, 1844, 1851, 1858, 1869, 1878, 1882, 1889, - 1892, 1898, 1898 + 0, 205, 205, 206, 209, 264, 267, 272, 277, 282, + 287, 293, 296, 299, 302, 305, 315, 328, 336, 436, + 439, 447, 450, 456, 460, 467, 473, 482, 490, 493, + 503, 506, 516, 526, 547, 548, 549, 554, 555, 563, + 574, 575, 583, 594, 598, 599, 609, 619, 629, 642, + 643, 653, 666, 670, 674, 678, 679, 692, 693, 706, + 707, 720, 721, 738, 739, 752, 753, 754, 755, 756, + 760, 763, 774, 782, 790, 817, 822, 833, 837, 841, + 845, 852, 907, 910, 917, 925, 946, 967, 977, 1005, + 1010, 1020, 1025, 1035, 1038, 1041, 1044, 1050, 1057, 1060, + 1064, 1068, 1072, 1079, 1083, 1087, 1094, 1098, 1102, 1123, + 1132, 1138, 1141, 1147, 1153, 1160, 1169, 1178, 1186, 1189, + 1196, 1200, 1207, 1210, 1214, 1218, 1227, 1236, 1244, 1254, + 1266, 1269, 1272, 1278, 1285, 1288, 1294, 1297, 1300, 1306, + 1309, 1324, 1328, 1332, 1336, 1340, 1344, 1349, 1354, 1359, + 1364, 1369, 1374, 1379, 1384, 1389, 1394, 1399, 1404, 1409, + 1414, 1419, 1424, 1429, 1434, 1439, 1444, 1449, 1453, 1457, + 1461, 1465, 1469, 1473, 1477, 1481, 1485, 1489, 1493, 1497, + 1501, 1505, 1509, 1517, 1525, 1529, 1542, 1542, 1545, 1545, + 1551, 1554, 1570, 1573, 1582, 1586, 1592, 1599, 1614, 1618, + 1622, 1623, 1629, 1630, 1631, 1632, 1633, 1637, 1638, 1638, + 1638, 1648, 1649, 1653, 1653, 1654, 1654, 1659, 1662, 1672, + 1675, 1681, 1682, 1686, 1694, 1698, 1708, 1713, 1730, 1730, + 1735, 1735, 1742, 1742, 1750, 1753, 1759, 1762, 1768, 1772, + 1779, 1786, 1793, 1800, 1811, 1820, 1824, 1831, 1834, 1840, + 1840 }; #endif @@ -745,13 +830,20 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "INVARIANT", "HIGH_PRECISION", "MEDIUM_PRECISION", "LOW_PRECISION", "PRECISION", "ATTRIBUTE", - "CONST_QUAL", "BOOL_TYPE", "FLOAT_TYPE", "INT_TYPE", "BREAK", "CONTINUE", - "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "BVEC2", "BVEC3", - "BVEC4", "IVEC2", "IVEC3", "IVEC4", "VEC2", "VEC3", "VEC4", "MATRIX2", + "CONST_QUAL", "BOOL_TYPE", "FLOAT_TYPE", "INT_TYPE", "UINT_TYPE", + "BREAK", "CONTINUE", "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", + "SWITCH", "CASE", "DEFAULT", "BVEC2", "BVEC3", "BVEC4", "IVEC2", "IVEC3", + "IVEC4", "VEC2", "VEC3", "VEC4", "UVEC2", "UVEC3", "UVEC4", "MATRIX2", "MATRIX3", "MATRIX4", "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM", - "VARYING", "STRUCT", "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE", - "SAMPLER_EXTERNAL_OES", "SAMPLER2DRECT", "IDENTIFIER", "TYPE_NAME", - "FLOATCONSTANT", "INTCONSTANT", "BOOLCONSTANT", "LEFT_OP", "RIGHT_OP", + "VARYING", "MATRIX2x3", "MATRIX3x2", "MATRIX2x4", "MATRIX4x2", + "MATRIX3x4", "MATRIX4x3", "CENTROID", "FLAT", "SMOOTH", "STRUCT", + "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE", "SAMPLER_EXTERNAL_OES", + "SAMPLER2DRECT", "SAMPLER2DARRAY", "ISAMPLER2D", "ISAMPLER3D", + "ISAMPLERCUBE", "ISAMPLER2DARRAY", "USAMPLER2D", "USAMPLER3D", + "USAMPLERCUBE", "USAMPLER2DARRAY", "SAMPLER3D", "SAMPLER3DRECT", + "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", "SAMPLER2DARRAYSHADOW", "LAYOUT", + "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", "INTCONSTANT", + "UINTCONSTANT", "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN", @@ -771,12 +863,15 @@ static const char *const yytname[] = "logical_and_expression", "logical_xor_expression", "logical_or_expression", "conditional_expression", "assignment_expression", "assignment_operator", "expression", - "constant_expression", "declaration", "function_prototype", - "function_declarator", "function_header_with_parameters", - "function_header", "parameter_declarator", "parameter_declaration", - "parameter_qualifier", "parameter_type_specifier", - "init_declarator_list", "single_declaration", "fully_specified_type", - "type_qualifier", "type_specifier", "precision_qualifier", + "constant_expression", "enter_struct", "declaration", + "function_prototype", "function_declarator", + "function_header_with_parameters", "function_header", + "parameter_declarator", "parameter_declaration", "parameter_qualifier", + "parameter_type_specifier", "init_declarator_list", "single_declaration", + "fully_specified_type", "interpolation_qualifier", + "parameter_type_qualifier", "type_qualifier", "storage_qualifier", + "type_specifier", "precision_qualifier", "layout_qualifier", + "layout_qualifier_id_list", "layout_qualifier_id", "type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier", "$@1", "$@2", "struct_declaration_list", "struct_declaration", "struct_declarator_list", "struct_declarator", "initializer", @@ -805,60 +900,73 @@ static const yytype_uint16 yytoknum[] = 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349 + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 95, 96, 96, 97, 98, 98, 98, 98, 98, - 99, 99, 99, 99, 99, 99, 100, 101, 102, 102, - 103, 103, 104, 104, 105, 105, 106, 107, 107, 108, - 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, - 111, 111, 112, 113, 113, 113, 113, 113, 114, 114, - 114, 115, 116, 117, 118, 118, 119, 119, 120, 120, - 121, 121, 122, 122, 123, 123, 123, 123, 123, 124, - 124, 125, 126, 126, 126, 127, 128, 128, 129, 129, - 130, 131, 131, 132, 132, 132, 132, 133, 133, 133, - 133, 134, 135, 135, 135, 135, 135, 136, 136, 136, - 136, 136, 136, 137, 137, 138, 138, 138, 138, 138, - 139, 139, 140, 140, 140, 141, 141, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 144, - 143, 145, 143, 146, 146, 147, 148, 148, 149, 149, - 150, 151, 152, 152, 153, 153, 153, 153, 153, 154, - 155, 156, 154, 157, 157, 159, 158, 160, 158, 161, - 161, 162, 162, 163, 163, 164, 165, 165, 166, 166, - 168, 167, 169, 167, 170, 167, 171, 171, 172, 172, - 173, 173, 174, 174, 174, 174, 174, 175, 175, 176, - 176, 178, 177 + 0, 128, 129, 129, 130, 131, 131, 131, 131, 131, + 131, 132, 132, 132, 132, 132, 132, 133, 134, 135, + 135, 136, 136, 137, 137, 138, 138, 139, 140, 140, + 141, 141, 141, 141, 142, 142, 142, 143, 143, 143, + 144, 144, 144, 145, 146, 146, 146, 146, 146, 147, + 147, 147, 148, 149, 150, 151, 151, 152, 152, 153, + 153, 154, 154, 155, 155, 156, 156, 156, 156, 156, + 157, 157, 158, 159, 160, 160, 160, 160, 160, 160, + 160, 161, 162, 162, 163, 163, 164, 165, 165, 166, + 166, 166, 166, 167, 167, 167, 167, 168, 169, 169, + 169, 169, 169, 170, 170, 170, 170, 170, 170, 171, + 171, 172, 172, 173, 174, 174, 174, 174, 174, 174, + 174, 174, 175, 175, 175, 175, 175, 175, 176, 176, + 177, 177, 177, 178, 179, 179, 180, 180, 180, 181, + 181, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 184, 183, 185, 183, + 186, 186, 187, 187, 188, 188, 189, 189, 190, 191, + 192, 192, 193, 193, 193, 193, 193, 194, 195, 196, + 194, 197, 197, 199, 198, 200, 198, 201, 201, 202, + 202, 203, 203, 204, 205, 205, 206, 206, 208, 207, + 209, 207, 210, 207, 211, 211, 212, 212, 213, 213, + 214, 214, 214, 214, 214, 215, 215, 216, 216, 218, + 217 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 1, 1, 1, 1, 1, 1, 3, - 1, 4, 1, 3, 2, 2, 1, 1, 1, 3, - 2, 2, 2, 1, 2, 3, 2, 1, 1, 1, - 2, 2, 2, 1, 1, 1, 1, 3, 3, 1, - 3, 3, 1, 1, 3, 3, 3, 3, 1, 3, - 3, 1, 1, 1, 1, 3, 1, 3, 1, 3, - 1, 5, 1, 3, 1, 1, 1, 1, 1, 1, - 3, 1, 2, 2, 4, 2, 1, 1, 2, 3, - 3, 2, 5, 3, 2, 3, 2, 0, 1, 1, - 1, 1, 1, 3, 5, 6, 5, 1, 2, 4, - 5, 4, 2, 1, 2, 1, 1, 1, 2, 1, - 1, 2, 1, 1, 1, 1, 4, 1, 1, 1, + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 1, 4, 1, 3, 2, 2, 1, 1, 1, + 3, 2, 2, 2, 1, 2, 3, 2, 1, 1, + 1, 2, 2, 2, 1, 1, 1, 1, 3, 3, + 1, 3, 3, 1, 1, 3, 3, 3, 3, 1, + 3, 3, 1, 1, 1, 1, 3, 1, 3, 1, + 3, 1, 5, 1, 3, 1, 1, 1, 1, 1, + 1, 3, 1, 2, 2, 2, 4, 5, 6, 9, + 2, 2, 1, 1, 2, 3, 3, 2, 5, 3, + 2, 3, 2, 0, 1, 1, 1, 1, 1, 3, + 5, 6, 5, 1, 2, 4, 5, 4, 2, 1, + 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, + 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, + 1, 1, 1, 4, 1, 3, 1, 3, 3, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 6, 0, 5, 1, 2, 3, 1, 3, 1, 4, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 0, 0, 5, 1, 1, 0, 2, 0, 2, 2, - 3, 1, 2, 1, 2, 5, 3, 1, 1, 4, - 0, 6, 0, 8, 0, 7, 1, 1, 1, 0, - 2, 3, 2, 2, 2, 3, 2, 1, 2, 1, - 1, 0, 3 + 1, 1, 1, 1, 1, 1, 0, 6, 0, 5, + 1, 2, 3, 4, 1, 3, 1, 4, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, + 5, 1, 1, 0, 2, 0, 2, 2, 3, 1, + 2, 1, 2, 5, 3, 1, 1, 4, 0, 6, + 0, 8, 0, 7, 1, 1, 1, 0, 2, 3, + 2, 2, 2, 3, 2, 1, 2, 1, 1, 0, + 3 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -866,421 +974,613 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 112, 113, 114, 0, 106, 105, 120, 118, - 119, 124, 125, 126, 127, 128, 129, 121, 122, 123, - 130, 131, 132, 109, 107, 0, 117, 133, 134, 135, - 136, 138, 200, 201, 0, 77, 87, 0, 92, 97, - 0, 103, 0, 110, 115, 137, 0, 197, 199, 108, - 102, 0, 2, 3, 141, 0, 72, 0, 75, 87, - 0, 88, 89, 90, 78, 0, 87, 0, 73, 2, - 98, 104, 111, 0, 1, 198, 0, 0, 139, 0, - 202, 79, 84, 86, 91, 0, 93, 80, 0, 0, - 4, 7, 6, 8, 0, 0, 0, 35, 34, 33, - 5, 10, 29, 12, 17, 18, 0, 0, 23, 0, - 36, 0, 39, 42, 43, 48, 51, 52, 53, 54, - 56, 58, 60, 71, 0, 27, 74, 0, 0, 143, - 0, 0, 0, 182, 0, 0, 0, 0, 0, 160, - 169, 173, 36, 62, 69, 0, 151, 0, 115, 154, - 171, 153, 152, 0, 155, 156, 157, 158, 81, 83, - 85, 0, 0, 99, 0, 150, 101, 30, 31, 0, - 14, 15, 0, 0, 21, 20, 0, 22, 24, 26, - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 116, 148, 0, 146, 142, - 144, 0, 193, 192, 167, 184, 0, 196, 194, 0, - 180, 159, 0, 65, 66, 67, 68, 64, 0, 0, - 174, 170, 172, 0, 94, 0, 96, 100, 9, 0, - 16, 2, 3, 13, 19, 25, 37, 38, 41, 40, - 46, 47, 44, 45, 49, 50, 55, 57, 59, 0, - 0, 0, 145, 140, 0, 0, 0, 0, 0, 195, - 0, 161, 63, 70, 0, 95, 11, 0, 0, 147, - 0, 166, 168, 187, 186, 189, 167, 178, 0, 0, - 0, 82, 61, 149, 0, 188, 0, 0, 177, 175, - 0, 0, 162, 0, 190, 0, 167, 0, 164, 181, - 163, 0, 191, 185, 176, 179, 183 + 0, 0, 130, 131, 132, 0, 114, 122, 145, 142, + 143, 144, 149, 150, 151, 152, 153, 154, 146, 147, + 148, 155, 156, 157, 158, 159, 160, 123, 124, 127, + 115, 161, 162, 163, 164, 165, 166, 0, 112, 111, + 0, 141, 167, 169, 182, 183, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 168, 179, 180, 181, 0, + 185, 248, 249, 0, 83, 93, 0, 98, 103, 119, + 0, 117, 109, 0, 120, 128, 139, 184, 0, 245, + 247, 116, 108, 0, 125, 126, 2, 3, 188, 0, + 0, 74, 0, 81, 93, 113, 94, 95, 96, 84, + 0, 93, 0, 75, 2, 104, 118, 0, 80, 0, + 110, 129, 121, 0, 1, 246, 0, 0, 186, 136, + 0, 134, 0, 250, 85, 90, 92, 97, 0, 99, + 86, 0, 0, 73, 0, 0, 0, 0, 190, 4, + 8, 6, 7, 9, 0, 0, 0, 36, 35, 34, + 5, 11, 30, 13, 18, 19, 0, 0, 24, 0, + 37, 0, 40, 43, 44, 49, 52, 53, 54, 55, + 57, 59, 61, 72, 0, 28, 76, 0, 0, 0, + 133, 0, 0, 0, 230, 0, 0, 0, 0, 0, + 208, 217, 221, 37, 63, 70, 0, 199, 0, 139, + 202, 219, 201, 200, 0, 203, 204, 205, 206, 87, + 89, 91, 0, 0, 105, 0, 198, 107, 0, 196, + 0, 194, 0, 191, 31, 32, 0, 15, 16, 0, + 0, 22, 21, 0, 23, 25, 27, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 140, 189, 0, 137, 138, 135, 241, 240, + 215, 232, 0, 244, 242, 0, 228, 207, 0, 66, + 67, 68, 69, 65, 0, 0, 222, 218, 220, 0, + 100, 0, 102, 106, 0, 0, 0, 192, 0, 77, + 10, 0, 17, 2, 3, 14, 20, 26, 38, 39, + 42, 41, 47, 48, 45, 46, 50, 51, 56, 58, + 60, 0, 187, 0, 0, 0, 0, 0, 243, 0, + 209, 64, 71, 0, 101, 193, 0, 195, 0, 78, + 12, 0, 0, 214, 216, 235, 234, 237, 215, 226, + 0, 0, 0, 0, 88, 197, 0, 62, 0, 236, + 0, 0, 225, 223, 0, 0, 210, 0, 0, 238, + 0, 215, 0, 212, 229, 211, 79, 0, 239, 233, + 224, 227, 231 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 196, 100, 101, 102, 229, 103, 104, 105, 106, - 107, 108, 109, 142, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 143, 144, 218, 145, - 124, 146, 147, 34, 35, 36, 82, 64, 65, 83, - 37, 38, 39, 40, 41, 42, 43, 125, 45, 130, - 77, 128, 129, 197, 198, 166, 149, 150, 151, 152, - 212, 280, 299, 254, 255, 256, 300, 153, 154, 155, - 289, 279, 156, 260, 204, 257, 275, 286, 287, 157, - 46, 47, 48, 57 + -1, 219, 150, 151, 152, 291, 153, 154, 155, 156, + 157, 158, 159, 193, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 194, 195, 274, 196, + 174, 109, 197, 198, 63, 64, 65, 125, 99, 100, + 126, 66, 67, 68, 69, 101, 70, 71, 72, 73, + 74, 120, 121, 75, 175, 77, 178, 117, 137, 138, + 220, 221, 217, 200, 201, 202, 203, 268, 343, 364, + 313, 314, 315, 365, 204, 205, 206, 353, 342, 207, + 319, 260, 316, 337, 350, 351, 208, 78, 79, 80, + 92 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -261 +#define YYPACT_NINF -309 static const yytype_int16 yypact[] = { - 1327, -20, -261, -261, -261, 113, -261, -261, -261, -261, - -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - -261, -261, -261, -261, -261, -19, -261, -261, -261, -261, - -261, -261, -261, -61, -40, -28, 75, -7, -261, 24, - 1370, -261, 1444, -261, -11, -261, 1283, -261, -261, -261, - -261, 1444, -261, -261, -261, 6, -261, 54, -261, 88, - 62, -261, -261, -261, -261, 1370, 59, 91, -261, 36, - -50, -261, -261, 1051, -261, -261, 63, 1370, -261, 293, - -261, -261, -261, -261, 91, 1370, -12, -261, 856, 1051, - 77, -261, -261, -261, 1051, 1051, 1051, -261, -261, -261, - -261, -261, -14, -261, -261, -261, 84, -44, 1116, 95, - -261, 1051, 53, 3, -261, -36, 89, -261, -261, -261, - 104, 107, -45, -261, 96, -261, -261, 91, 1184, -261, - 1370, 92, 93, -261, 98, 101, 94, 921, 105, 102, - -261, -261, 72, -261, -261, 9, -261, -61, 42, -261, - -261, -261, -261, 376, -261, -261, -261, -261, 106, -261, - -261, 986, 1051, -261, 103, -261, -261, -261, -261, -41, - -261, -261, 1051, 1407, -261, -261, 1051, 110, -261, -261, - -261, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 1051, - 1051, 1051, 1051, 1051, 1051, -261, 109, 23, -261, -261, - -261, 1227, -261, -261, 111, -261, 1051, -261, -261, 25, - -261, -261, 459, -261, -261, -261, -261, -261, 1051, 1051, - -261, -261, -261, 1051, -261, 114, -261, -261, -261, 115, - 112, 77, 116, -261, -261, -261, -261, -261, 53, 53, - -261, -261, -261, -261, -36, -36, -261, 104, 107, 76, - 1051, 91, -261, -261, 145, 54, 625, 708, -6, -261, - 791, 459, -261, -261, 117, -261, -261, 1051, 120, -261, - 124, -261, -261, -261, -261, 791, 111, 112, 91, 125, - 122, -261, -261, -261, 1051, -261, 118, 128, 180, -261, - 126, 542, -261, -5, 1051, 542, 111, 1051, -261, -261, - -261, 123, 112, -261, -261, -261, -261 + 2013, -27, -309, -309, -309, 154, -309, -309, -309, -309, + -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, + -309, -309, -309, -309, -309, -309, -309, -309, -309, -309, + -309, -309, -309, -309, -309, -309, -309, 98, -309, -309, + -40, -309, -309, -309, -309, -309, -309, -309, -309, -309, + -309, -309, -309, -309, -309, -309, -309, -309, -309, -46, + -309, -309, -42, -23, 8, 5, -87, -309, 91, 14, + 1130, -309, -309, 2298, 14, -309, -1, -309, 1938, -309, + -309, -309, -309, 2298, -309, -309, -309, -309, -309, 13, + 47, -309, 43, -309, 39, -309, -309, -309, -309, -309, + 2162, 124, 94, -309, 51, -14, -309, 66, -309, 2088, + -309, -309, -309, 1491, -309, -309, 62, 2088, -309, 48, + -83, -309, 358, -309, -309, -309, -309, 94, 2162, -9, + -309, 1200, 1491, -309, 148, 2162, 94, 1683, -309, 89, + -309, -309, -309, -309, 1491, 1491, 1491, -309, -309, -309, + -309, -309, 10, -309, -309, -309, 92, 20, 1586, 96, + -309, 1491, 53, -76, -309, -62, 90, -309, -309, -309, + 104, 101, -61, -309, 95, -309, -309, 1768, 2088, 103, + -309, 47, 82, 84, -309, 97, 99, 93, 1298, 105, + 102, -309, -309, -10, -309, -309, -13, -309, -42, 2, + -309, -309, -309, -309, 474, -309, -309, -309, -309, 106, + -309, -309, 1393, 1491, -309, 107, -309, -309, 94, 109, + 4, -309, -58, -309, -309, -309, 22, -309, -309, 1491, + 2230, -309, -309, 1491, 112, -309, -309, -309, 1491, 1491, + 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, + 1491, 1491, -309, -309, 1853, -309, -309, -309, -309, -309, + 100, -309, 1491, -309, -309, 36, -309, -309, 590, -309, + -309, -309, -309, -309, 1491, 1491, -309, -309, -309, 1491, + -309, 113, -309, -309, 42, 1491, 94, -309, -73, -309, + -309, 115, 108, 89, 119, -309, -309, -309, -309, -309, + 53, 53, -309, -309, -309, -309, -62, -62, -309, 104, + 101, 73, -309, 169, 43, 822, 938, 25, -309, 1035, + 590, -309, -309, 120, -309, -309, 121, -309, 1491, -309, + -309, 1491, 122, -309, -309, -309, -309, 1035, 100, 108, + 94, 2162, 125, 123, -309, -309, 126, -309, 1491, -309, + 117, 129, 212, -309, 139, 706, -309, 141, 29, 1491, + 706, 100, 1491, -309, -309, -309, -309, 142, 108, -309, + -309, -309, -309 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -261, -24, -261, -261, -261, -261, -261, -261, 34, -261, - -261, -261, -261, 32, -261, -33, -261, -27, -26, -261, - -261, -261, 14, 16, 18, -261, -66, -87, -261, -92, - -85, 11, 12, -261, -261, -261, 141, 150, 161, 143, - -261, -261, -231, 5, -30, 224, -18, 0, -261, -261, - -261, 100, -119, -261, -17, -156, -25, -145, -243, -261, - -261, -261, -64, -260, -261, -261, -52, 21, -22, -261, - -261, -39, -261, -261, -261, -261, -261, -261, -261, -261, - -261, 191, -261, -261 + -309, -39, -309, -309, -309, -309, -309, -309, 7, -309, + -309, -309, -309, 1, -309, -54, -309, -101, -57, -309, + -309, -309, 9, -11, 3, -309, -110, -126, -309, -138, + -122, -309, 11, 16, -309, -309, -309, 130, 165, 159, + 133, -309, -309, -299, -309, -309, -102, -30, -66, 257, + -309, -309, 83, -6, 0, -309, -309, -309, -104, -125, + 45, -21, -208, -50, -194, -296, -309, -309, -309, -93, + -308, -309, -309, -90, 6, -47, -309, -309, -67, -309, + -309, -309, -309, -309, -309, -309, -309, -309, 193, -309, + -309 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -166 +#define YYTABLE_NINF -214 static const yytype_int16 yytable[] = { - 44, 55, 165, 164, 169, 80, 226, 123, 222, 200, - 71, 32, 33, 272, 193, 70, 288, 49, 185, 186, - 56, 178, 123, 88, 72, 50, 52, 53, 175, 278, - 89, 228, 58, 76, 176, 84, 304, 219, 170, 171, - 44, 66, 44, 86, 278, 209, 44, 127, 298, 194, - 59, 44, 298, 187, 188, 84, 54, 32, 33, 172, - 158, 161, 73, 173, 66, 44, 276, 301, 162, 69, - 53, 67, 219, 219, 68, 165, 225, 44, 60, 148, - 230, 78, 200, 6, 7, 44, 183, 219, 184, 235, - 220, 60, 61, 62, 63, 123, 6, 7, 127, 49, - 127, 251, 249, 219, 252, 110, 259, 87, 61, 62, - 63, 23, 24, -27, 258, 73, 222, 2, 3, 4, - 110, 61, 62, 63, 23, 24, 167, 168, 44, 79, - 44, 262, 263, 213, 214, 215, 52, 53, 264, 181, - 182, 305, 216, 180, 126, 189, 190, -76, -28, 233, - 238, 239, 217, 148, 219, 267, 174, 123, 240, 241, - 242, 243, 191, 244, 245, 268, 179, 192, 277, 205, - 195, 127, 206, 202, 203, 207, 210, 227, 211, 223, - 282, -117, 250, 277, 123, 270, -165, -138, 265, 266, - 219, 281, 293, 110, 283, 284, 296, 291, 292, 294, - 295, 44, 302, 271, 306, 246, 297, 234, 247, 81, - 165, 248, 148, 236, 237, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 159, 85, 160, 51, - 201, 303, 273, 261, 269, 274, 285, 75, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 290, 110, 148, 148, 0, 0, - 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 148, 0, 0, 0, 0, - 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, - 0, 148, 0, 0, 0, 148, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 131, 132, 133, 0, - 134, 135, 136, 137, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 0, 23, - 24, 25, 26, 138, 27, 28, 29, 30, 90, 31, - 91, 92, 93, 0, 0, 94, 95, 0, 0, 0, + 76, 89, 123, 173, 110, 282, 216, 135, 226, 215, + 278, 61, 223, 177, 95, 135, 62, 81, 288, 334, + 340, 173, 180, 7, 102, 242, 243, 103, 181, 105, + 352, 250, 235, 328, 127, 135, 86, 87, 340, 106, + 240, 329, 241, 136, 112, 96, 97, 98, 95, 82, + 265, 136, 223, 370, 27, 28, 289, 29, 90, 363, + 244, 245, 127, 129, 363, 37, 251, 111, 88, 218, + 76, 136, 91, 76, 254, 135, 135, 116, 76, 96, + 97, 98, 93, 76, 269, 270, 271, 216, 209, 61, + 281, 292, 131, 272, 62, 227, 228, 212, 275, 132, + 76, 276, 173, 273, 213, 113, -28, 297, 113, 76, + -82, 136, 136, 311, 160, 286, 229, 76, 287, 94, + 230, 118, 199, 119, 317, 232, 278, 290, 76, 223, + 338, 233, 160, 275, 367, 76, 275, 76, 84, 85, + 275, 302, 303, 304, 305, 224, 225, 275, 321, 322, + 318, 122, 135, 286, 371, 130, 325, 323, 2, 3, + 4, 179, 237, 326, 96, 97, 98, 104, 87, 173, + 86, 87, 238, 239, 133, 173, 176, 76, 76, 246, + 247, 339, 255, 256, 275, 331, 300, 301, 136, 306, + 307, 295, 81, -29, 249, 248, 258, 231, 259, 339, + 236, 261, 252, 262, 199, 347, 346, 263, -213, 266, + 358, 267, 279, 160, 283, 285, -141, 341, 173, 275, + 324, 368, 330, -185, 333, 332, 348, 344, 345, 361, + 355, 359, 356, 357, 360, 341, 216, 296, 309, 298, + 299, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 362, 310, 76, 366, 372, 308, 210, 124, + 128, 211, 83, 284, 257, 327, 335, 369, 199, 336, + 349, 115, 0, 0, 320, 110, 0, 0, 0, 0, + 160, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 0, 0, 0, 139, 140, - 0, 0, 0, 0, 141, 97, 98, 0, 99, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 131, - 132, 133, 0, 134, 135, 136, 137, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 0, 0, 23, 24, 25, 26, 138, 27, 28, 29, - 30, 90, 31, 91, 92, 93, 0, 0, 94, 95, + 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 199, 199, 0, 0, 199, + 199, 0, 0, 0, 0, 0, 0, 0, 0, 160, + 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, + 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, + 199, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 182, 183, 184, 0, 185, 186, 187, 188, + 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 189, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 59, 139, 60, 140, 141, 142, 143, + 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, - 0, 139, 221, 0, 0, 0, 0, 141, 97, 98, - 0, 99, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 131, 132, 133, 0, 134, 135, 136, 137, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 23, 24, 25, 26, 138, - 27, 28, 29, 30, 90, 31, 91, 92, 93, 0, - 0, 94, 95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 146, 0, 0, 0, 190, 191, 0, 0, + 0, 0, 192, 147, 148, 0, 149, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 182, 183, + 184, 0, 185, 186, 187, 188, 0, 0, 0, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 189, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, + 139, 60, 140, 141, 142, 143, 0, 0, 0, 144, + 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, + 0, 0, 190, 277, 0, 0, 0, 0, 192, 147, + 148, 0, 149, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 182, 183, 184, 0, 185, 186, + 187, 188, 0, 0, 0, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 0, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 189, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 0, 56, 57, 58, 59, 139, 60, 140, 141, + 142, 143, 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 0, 0, 0, 139, 0, 0, 0, 0, 0, - 141, 97, 98, 0, 99, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 131, 132, 133, 0, 134, - 135, 136, 137, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 0, 0, 0, 23, 24, - 25, 26, 138, 27, 28, 29, 30, 90, 31, 91, - 92, 93, 0, 0, 94, 95, 0, 0, 0, 0, + 0, 0, 0, 0, 146, 0, 0, 0, 190, 0, + 0, 0, 0, 0, 192, 147, 148, 0, 149, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 182, 183, 184, 0, 185, 186, 187, 188, 0, 0, + 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 0, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 189, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, + 58, 59, 139, 60, 140, 141, 142, 143, 0, 0, + 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 79, 0, 0, - 0, 0, 0, 141, 97, 98, 0, 99, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 131, 132, - 133, 0, 134, 135, 136, 137, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 0, 23, 24, 25, 26, 138, 27, 28, 29, 30, - 90, 31, 91, 92, 93, 0, 0, 94, 95, 0, + 146, 0, 0, 0, 122, 0, 0, 0, 0, 0, + 192, 147, 148, 0, 149, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 182, 183, 184, 0, + 185, 186, 187, 188, 0, 0, 0, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 0, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 189, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 0, 56, 57, 58, 59, 139, 60, + 140, 141, 142, 143, 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 141, 97, 98, 0, - 99, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 192, 147, 148, 0, + 149, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 59, 139, 60, 140, 141, 142, 143, + 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 134, 2, + 3, 4, 146, 6, 7, 8, 9, 10, 11, 0, + 0, 0, 192, 147, 148, 0, 149, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 0, 0, 0, 23, 24, 25, 26, 0, 27, - 28, 29, 30, 90, 31, 91, 92, 93, 0, 0, - 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, - 97, 98, 0, 99, 60, 2, 3, 4, 0, 6, - 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, - 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 0, 23, 24, 25, - 26, 0, 27, 28, 29, 30, 90, 31, 91, 92, - 93, 0, 0, 94, 95, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 8, 9, 10, 0, - 0, 0, 0, 97, 98, 0, 99, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 0, 0, 0, 0, 25, 26, 0, 27, 28, 29, - 30, 90, 31, 91, 92, 93, 0, 0, 94, 95, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, - 163, 8, 9, 10, 0, 0, 0, 0, 97, 98, - 0, 99, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 0, 0, 0, 25, - 26, 0, 27, 28, 29, 30, 90, 31, 91, 92, - 93, 0, 0, 94, 95, 0, 0, 0, 0, 0, + 22, 23, 24, 25, 26, 27, 28, 0, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 0, 56, 57, 58, + 59, 139, 60, 140, 141, 142, 143, 0, 0, 0, + 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 3, 4, 0, 0, 146, + 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, + 147, 148, 0, 149, 0, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, + 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 0, 56, 57, 58, 0, 107, 60, 0, 0, + 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 0, 0, 0, 0, 108, 31, 32, 33, 34, 35, + 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 0, 56, 57, 58, 0, 139, 60, 140, 141, + 142, 143, 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 8, 9, 10, 0, - 0, 0, 208, 97, 98, 0, 99, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 0, 0, 0, 0, 25, 26, 0, 27, 28, 29, - 30, 90, 31, 91, 92, 93, 0, 0, 94, 95, + 0, 0, 0, 0, 146, 0, 0, 214, 8, 9, + 10, 11, 0, 0, 0, 147, 148, 0, 149, 0, + 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, + 0, 0, 0, 31, 32, 33, 34, 35, 36, 0, + 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 0, 139, 60, 140, 141, 142, 143, + 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, - 224, 8, 9, 10, 0, 0, 0, 0, 97, 98, - 0, 99, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 0, 0, 0, 25, - 26, 0, 27, 28, 29, 30, 90, 31, 91, 92, - 93, 0, 0, 94, 95, 0, 0, 0, 0, 0, + 0, 0, 146, 8, 9, 10, 11, 0, 0, 0, + 0, 0, 264, 147, 148, 0, 149, 0, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, + 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 0, 139, + 60, 140, 141, 142, 143, 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 8, 9, 10, 0, - 0, 0, 0, 97, 98, 0, 99, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 0, 0, 0, 0, 25, 177, 0, 27, 28, 29, - 30, 90, 31, 91, 92, 93, 0, 0, 94, 95, + 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, + 280, 8, 9, 10, 11, 0, 0, 0, 147, 148, + 0, 149, 0, 0, 0, 0, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 0, 0, 0, 0, 0, 31, 32, 33, 34, + 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 0, 56, 57, 58, 0, 139, 60, 140, + 141, 142, 143, 0, 0, 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 2, 3, - 4, 0, 0, 0, 8, 9, 10, 0, 97, 98, - 0, 99, 0, 0, 0, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, - 0, 0, 25, 26, 0, 27, 28, 29, 30, 0, - 31, 2, 3, 4, 0, 0, 0, 8, 9, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 199, 0, 0, 0, 0, 25, 26, 0, 27, 28, - 29, 30, 0, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 74, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, - 0, 0, 0, 253, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 0, 23, - 24, 25, 26, 0, 27, 28, 29, 30, 0, 31, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 0, 0, 23, 24, 25, 26, 0, 27, 28, - 29, 30, 0, 31, 2, 3, 4, 0, 0, 0, - 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 0, 0, 0, 0, 0, 25, 26, - 0, 27, 28, 29, 30, 0, 31, 8, 9, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 0, 0, 0, 0, 25, 26, 0, 27, 28, - 29, 30, 231, 232, 8, 9, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, - 0, 0, 25, 26, 0, 27, 28, 29, 30, 0, - 31 + 0, 0, 0, 0, 0, 146, 8, 9, 10, 11, + 0, 0, 0, 0, 0, 0, 147, 148, 0, 149, + 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, + 0, 31, 32, 33, 34, 35, 36, 0, 0, 0, + 40, 234, 0, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, + 58, 0, 139, 60, 140, 141, 142, 143, 0, 0, + 0, 144, 145, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 134, 2, 3, 4, + 146, 6, 7, 8, 9, 10, 11, 0, 0, 0, + 0, 147, 148, 0, 149, 0, 0, 0, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 0, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 59, 0, + 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 134, 2, 3, 4, 0, 6, 7, 8, 9, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 222, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 59, 0, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 134, 2, 3, 4, + 0, 6, 7, 8, 9, 10, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 253, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 0, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 59, 0, + 60, 0, 0, 0, 0, 0, 0, 0, 114, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 312, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 59, 0, 60, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 0, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 59, 0, + 60, 134, 2, 3, 4, 0, 6, 7, 8, 9, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 59, 0, 60, 2, 3, 4, 0, + 0, 0, 8, 9, 10, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 0, 0, 0, 0, 0, 31, 32, 33, + 34, 35, 36, 0, 0, 0, 40, 41, 0, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 0, 56, 57, 58, 0, 0, 60, + 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, + 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 0, 56, 57, 58, 0, 293, 294, 8, 9, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, + 0, 0, 0, 31, 32, 33, 34, 35, 36, 0, + 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, + 56, 57, 58, 0, 0, 60 }; #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-261))) + (!!((Yystate) == (-309))) #define yytable_value_is_error(Yytable_value) \ YYID (0) static const yytype_int16 yycheck[] = { - 0, 25, 89, 88, 96, 57, 162, 73, 153, 128, - 40, 0, 0, 256, 59, 39, 276, 37, 54, 55, - 81, 108, 88, 73, 42, 45, 45, 46, 72, 260, - 80, 72, 72, 51, 78, 65, 296, 78, 52, 53, - 40, 36, 42, 67, 275, 137, 46, 77, 291, 94, - 78, 51, 295, 89, 90, 85, 75, 46, 46, 73, - 84, 73, 73, 77, 59, 65, 72, 72, 80, 45, - 46, 78, 78, 78, 81, 162, 161, 77, 3, 79, - 172, 75, 201, 8, 9, 85, 83, 78, 85, 176, - 81, 3, 33, 34, 35, 161, 8, 9, 128, 37, - 130, 78, 194, 78, 81, 73, 81, 71, 33, 34, - 35, 36, 37, 71, 206, 73, 261, 4, 5, 6, - 88, 33, 34, 35, 36, 37, 94, 95, 128, 75, - 130, 218, 219, 61, 62, 63, 45, 46, 223, 86, - 87, 297, 70, 111, 81, 56, 57, 72, 71, 173, - 183, 184, 80, 153, 78, 79, 72, 223, 185, 186, - 187, 188, 58, 189, 190, 250, 71, 60, 260, 71, - 74, 201, 71, 81, 81, 81, 71, 74, 76, 73, - 267, 71, 73, 275, 250, 40, 75, 71, 74, 74, - 78, 74, 284, 161, 74, 71, 16, 72, 76, 81, - 72, 201, 294, 255, 81, 191, 80, 173, 192, 59, - 297, 193, 212, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 85, 66, 85, 5, - 130, 295, 257, 212, 251, 257, 275, 46, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 278, 223, 256, 257, -1, -1, - 260, 261, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 275, -1, -1, -1, -1, - -1, -1, 250, -1, -1, -1, -1, -1, -1, -1, - -1, 291, -1, -1, -1, 295, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, -1, -1, -1, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, -1, -1, 52, 53, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 71, -1, -1, -1, 75, 76, - -1, -1, -1, -1, 81, 82, 83, -1, 85, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, -1, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, - -1, -1, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, -1, -1, 52, 53, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, - -1, 75, 76, -1, -1, -1, -1, 81, 82, 83, - -1, 85, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, -1, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, -1, -1, -1, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, -1, - -1, 52, 53, -1, -1, -1, -1, -1, -1, -1, + 0, 40, 92, 113, 70, 213, 132, 109, 146, 131, + 204, 0, 137, 117, 9, 117, 0, 44, 76, 315, + 319, 131, 105, 9, 111, 87, 88, 114, 111, 68, + 338, 92, 158, 106, 100, 137, 76, 77, 337, 69, + 116, 114, 118, 109, 74, 40, 41, 42, 9, 76, + 188, 117, 177, 361, 40, 41, 114, 43, 104, 355, + 122, 123, 128, 102, 360, 51, 127, 73, 108, 135, + 70, 137, 114, 73, 178, 177, 178, 83, 78, 40, + 41, 42, 105, 83, 94, 95, 96, 213, 127, 78, + 212, 229, 106, 103, 78, 85, 86, 106, 111, 113, + 100, 114, 212, 113, 113, 106, 104, 233, 106, 109, + 105, 177, 178, 251, 113, 111, 106, 117, 114, 111, + 110, 108, 122, 76, 262, 105, 320, 105, 128, 254, + 105, 111, 131, 111, 105, 135, 111, 137, 40, 41, + 111, 242, 243, 244, 245, 144, 145, 111, 274, 275, + 114, 108, 254, 111, 362, 104, 114, 279, 4, 5, + 6, 113, 161, 285, 40, 41, 42, 76, 77, 279, + 76, 77, 119, 120, 108, 285, 114, 177, 178, 89, + 90, 319, 79, 80, 111, 112, 240, 241, 254, 246, + 247, 230, 44, 104, 93, 91, 114, 105, 114, 337, + 104, 104, 107, 104, 204, 331, 328, 114, 108, 104, + 348, 109, 106, 212, 107, 106, 104, 319, 328, 111, + 107, 359, 107, 104, 314, 56, 104, 107, 107, 17, + 105, 114, 109, 107, 105, 337, 362, 230, 249, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 113, 250, 254, 114, 114, 248, 128, 94, + 101, 128, 5, 218, 181, 286, 316, 360, 268, 316, + 337, 78, -1, -1, 268, 341, -1, -1, -1, -1, + 279, -1, -1, -1, -1, -1, 285, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 71, -1, -1, -1, 75, -1, -1, -1, -1, -1, - 81, 82, 83, -1, 85, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, -1, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, -1, -1, -1, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, -1, -1, 52, 53, -1, -1, -1, -1, + -1, 340, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 315, 316, -1, -1, 319, + 320, -1, -1, -1, -1, -1, -1, -1, -1, 328, + -1, -1, -1, -1, -1, -1, -1, 337, -1, -1, + -1, 341, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 355, -1, -1, -1, -1, + 360, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, -1, 18, 19, 20, 21, + -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 71, -1, -1, -1, 75, -1, -1, - -1, -1, -1, 81, 82, 83, -1, 85, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, -1, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, - -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, -1, -1, 52, 53, -1, + -1, -1, 104, -1, -1, -1, 108, 109, -1, -1, + -1, -1, 114, 115, 116, -1, 118, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, -1, 18, 19, 20, 21, -1, -1, -1, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, -1, -1, -1, 85, + 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, + -1, -1, 108, 109, -1, -1, -1, -1, 114, 115, + 116, -1, 118, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, -1, 18, 19, + 20, 21, -1, -1, -1, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 81, 82, 83, -1, - 85, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, -1, -1, -1, -1, -1, -1, -1, -1, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, -1, -1, -1, 36, 37, 38, 39, -1, 41, - 42, 43, 44, 45, 46, 47, 48, 49, -1, -1, - 52, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, - 82, 83, -1, 85, 3, 4, 5, 6, -1, 8, - 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, - -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, -1, -1, 36, 37, 38, - 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, - 49, -1, -1, 52, 53, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 104, -1, -1, -1, 108, -1, + -1, -1, -1, -1, 114, 115, 116, -1, 118, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, -1, 18, 19, 20, 21, -1, -1, + -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, -1, -1, + -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 71, -1, -1, -1, 10, 11, 12, -1, - -1, -1, -1, 82, 83, -1, 85, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - 44, 45, 46, 47, 48, 49, -1, -1, 52, 53, + 104, -1, -1, -1, 108, -1, -1, -1, -1, -1, + 114, 115, 116, -1, 118, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, + 18, 19, 20, 21, -1, -1, -1, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, - 74, 10, 11, 12, -1, -1, -1, -1, 82, 83, - -1, 85, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, -1, -1, -1, -1, 38, - 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, - 49, -1, -1, 52, 53, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 104, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 114, 115, 116, -1, + 118, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, + 5, 6, 104, 8, 9, 10, 11, 12, 13, -1, + -1, -1, 114, 115, 116, -1, 118, -1, -1, -1, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, -1, -1, -1, + 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4, 5, 6, -1, -1, 104, + 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, + 115, 116, -1, 118, -1, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, + 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, -1, 72, 73, 74, -1, 76, 77, -1, -1, + 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + -1, -1, -1, -1, 114, 45, 46, 47, 48, 49, + 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, -1, 72, 73, 74, -1, 76, 77, 78, 79, + 80, 81, -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 71, -1, -1, -1, 10, 11, 12, -1, - -1, -1, 81, 82, 83, -1, 85, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - 44, 45, 46, 47, 48, 49, -1, -1, 52, 53, + -1, -1, -1, -1, 104, -1, -1, 107, 10, 11, + 12, 13, -1, -1, -1, 115, 116, -1, 118, -1, + -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, + -1, -1, -1, 45, 46, 47, 48, 49, 50, -1, + -1, -1, 54, 55, -1, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, + -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, - 74, 10, 11, 12, -1, -1, -1, -1, 82, 83, - -1, 85, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, -1, -1, -1, -1, 38, - 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, - 49, -1, -1, 52, 53, -1, -1, -1, -1, -1, + -1, -1, 104, 10, 11, 12, 13, -1, -1, -1, + -1, -1, 114, 115, 116, -1, 118, -1, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, + 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, -1, 76, + 77, 78, 79, 80, 81, -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 71, -1, -1, -1, 10, 11, 12, -1, - -1, -1, -1, 82, 83, -1, 85, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - 44, 45, 46, 47, 48, 49, -1, -1, 52, 53, + -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, + 107, 10, 11, 12, 13, -1, -1, -1, 115, 116, + -1, 118, -1, -1, -1, -1, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, + 49, 50, -1, -1, -1, 54, 55, -1, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, -1, 72, 73, 74, -1, 76, 77, 78, + 79, 80, 81, -1, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 71, 4, 5, - 6, -1, -1, -1, 10, 11, 12, -1, 82, 83, - -1, 85, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, - -1, -1, 38, 39, -1, 41, 42, 43, 44, -1, - 46, 4, 5, 6, -1, -1, -1, 10, 11, 12, - -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 76, -1, -1, -1, -1, 38, 39, -1, 41, 42, - 43, 44, -1, 46, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 0, -1, -1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, - -1, -1, -1, 76, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, -1, -1, -1, 36, - 37, 38, 39, -1, 41, 42, 43, 44, -1, 46, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - -1, -1, -1, 36, 37, 38, 39, -1, 41, 42, - 43, 44, -1, 46, 4, 5, 6, -1, -1, -1, - 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, - -1, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, -1, -1, -1, -1, -1, 38, 39, - -1, 41, 42, 43, 44, -1, 46, 10, 11, 12, - -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 10, 11, 12, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, - -1, -1, 38, 39, -1, 41, 42, 43, 44, -1, - 46 + -1, -1, -1, -1, -1, 104, 10, 11, 12, 13, + -1, -1, -1, -1, -1, -1, 115, 116, -1, 118, + -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, + -1, 45, 46, 47, 48, 49, 50, -1, -1, -1, + 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, + 74, -1, 76, 77, 78, 79, 80, 81, -1, -1, + -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, + 104, 8, 9, 10, 11, 12, 13, -1, -1, -1, + -1, 115, 116, -1, 118, -1, -1, -1, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, 75, -1, + 77, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3, 4, 5, 6, -1, 8, 9, 10, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 109, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, 75, -1, 77, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, + -1, 8, 9, 10, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 109, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, 75, -1, + 77, -1, -1, -1, -1, -1, -1, -1, 0, -1, + -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 109, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, 75, -1, 77, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, 75, -1, + 77, 3, 4, 5, 6, -1, 8, 9, 10, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, 75, -1, 77, 4, 5, 6, -1, + -1, -1, 10, 11, 12, 13, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, -1, -1, -1, -1, -1, 45, 46, 47, + 48, 49, 50, -1, -1, -1, 54, 55, -1, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, -1, 72, 73, 74, -1, -1, 77, + 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, + 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, -1, 72, 73, 74, -1, 76, 77, 10, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, + -1, -1, -1, 45, 46, 47, 48, 49, 50, -1, + -1, -1, 54, 55, -1, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, + 72, 73, 74, -1, -1, 77 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1288,36 +1588,43 @@ static const yytype_int16 yycheck[] = static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 36, 37, 38, 39, 41, 42, 43, - 44, 46, 126, 127, 128, 129, 130, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 175, 176, 177, 37, - 45, 140, 45, 46, 75, 96, 81, 178, 72, 78, - 3, 33, 34, 35, 132, 133, 138, 78, 81, 45, - 96, 139, 141, 73, 0, 176, 141, 145, 75, 75, - 161, 132, 131, 134, 139, 133, 96, 71, 73, 80, - 45, 47, 48, 49, 52, 53, 71, 82, 83, 85, - 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 125, 142, 81, 139, 146, 147, - 144, 13, 14, 15, 17, 18, 19, 20, 40, 75, - 76, 81, 108, 121, 122, 124, 126, 127, 142, 151, - 152, 153, 154, 162, 163, 164, 167, 174, 96, 131, - 134, 73, 80, 74, 125, 122, 150, 108, 108, 124, - 52, 53, 73, 77, 72, 72, 78, 39, 122, 71, - 108, 86, 87, 83, 85, 54, 55, 89, 90, 56, - 57, 58, 60, 59, 94, 74, 96, 148, 149, 76, - 147, 146, 81, 81, 169, 71, 71, 81, 81, 124, - 71, 76, 155, 61, 62, 63, 70, 80, 123, 78, - 81, 76, 152, 73, 74, 125, 150, 74, 72, 100, - 124, 45, 46, 96, 103, 122, 108, 108, 110, 110, - 112, 112, 112, 112, 113, 113, 117, 118, 119, 124, - 73, 78, 81, 76, 158, 159, 160, 170, 124, 81, - 168, 162, 122, 122, 125, 74, 74, 79, 125, 149, - 40, 161, 153, 151, 163, 171, 72, 124, 137, 166, - 156, 74, 122, 74, 71, 166, 172, 173, 158, 165, - 96, 72, 76, 124, 81, 72, 16, 80, 153, 157, - 161, 72, 124, 157, 158, 150, 81 + 12, 13, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, + 77, 160, 161, 162, 163, 164, 169, 170, 171, 172, + 174, 175, 176, 177, 178, 181, 182, 183, 215, 216, + 217, 44, 76, 177, 40, 41, 76, 77, 108, 129, + 104, 114, 218, 105, 111, 9, 40, 41, 42, 166, + 167, 173, 111, 114, 76, 129, 175, 76, 114, 159, + 176, 181, 175, 106, 0, 216, 181, 185, 108, 76, + 179, 180, 108, 201, 166, 165, 168, 176, 167, 129, + 104, 106, 113, 108, 3, 174, 176, 186, 187, 76, + 78, 79, 80, 81, 85, 86, 104, 115, 116, 118, + 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 158, 182, 114, 186, 184, 113, + 105, 111, 14, 15, 16, 18, 19, 20, 21, 56, + 108, 109, 114, 141, 154, 155, 157, 160, 161, 182, + 191, 192, 193, 194, 202, 203, 204, 207, 214, 129, + 165, 168, 106, 113, 107, 158, 155, 190, 176, 129, + 188, 189, 109, 187, 141, 141, 157, 85, 86, 106, + 110, 105, 105, 111, 55, 155, 104, 141, 119, 120, + 116, 118, 87, 88, 122, 123, 89, 90, 91, 93, + 92, 127, 107, 109, 186, 79, 80, 180, 114, 114, + 209, 104, 104, 114, 114, 157, 104, 109, 195, 94, + 95, 96, 103, 113, 156, 111, 114, 109, 192, 106, + 107, 158, 190, 107, 188, 106, 111, 114, 76, 114, + 105, 133, 157, 76, 77, 129, 136, 155, 141, 141, + 143, 143, 145, 145, 145, 145, 146, 146, 150, 151, + 152, 157, 109, 198, 199, 200, 210, 157, 114, 208, + 202, 155, 155, 158, 107, 114, 158, 189, 106, 114, + 107, 112, 56, 201, 193, 191, 203, 211, 105, 157, + 171, 174, 206, 196, 107, 107, 158, 155, 104, 206, + 212, 213, 198, 205, 129, 105, 109, 107, 157, 114, + 105, 17, 113, 193, 197, 201, 114, 105, 157, 197, + 198, 190, 114 }; #define yyerrok (yyerrstatus = 0) @@ -1512,11 +1819,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) # else YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -1916,12 +2219,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YYUSE (yytype); } @@ -2248,43 +2546,55 @@ yyreduce: { // The symbol table search was done in the lexical phase - const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol; - const TVariable* variable; - if (symbol == 0) { + const TSymbol *symbol = (yyvsp[(1) - (1)].lex).symbol; + const TVariable *variable = 0; + + if (!symbol) + { context->error((yylsp[(1) - (1)]), "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str()); context->recover(); - TType type(EbtFloat, EbpUndefined); - TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type); - context->symbolTable.insert(*fakeVariable); - variable = fakeVariable; - } else { - // This identifier can only be a variable type symbol - if (! symbol->isVariable()) { - context->error((yylsp[(1) - (1)]), "variable expected", (yyvsp[(1) - (1)].lex).string->c_str()); - context->recover(); - } - + } + else if (!symbol->isVariable()) + { + context->error((yylsp[(1) - (1)]), "variable expected", (yyvsp[(1) - (1)].lex).string->c_str()); + context->recover(); + } + else + { variable = static_cast<const TVariable*>(symbol); - if (context->symbolTable.findBuiltIn(variable->getName()) && + if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) && !variable->getExtension().empty() && - context->extensionErrorCheck((yylsp[(1) - (1)]), variable->getExtension())) { + context->extensionErrorCheck((yylsp[(1) - (1)]), variable->getExtension())) + { context->recover(); } } - // don't delete $1.string, it's used by error recovery, and the pool - // pop will reclaim the memory + if (!variable) + { + TType type(EbtFloat, EbpUndefined); + TVariable *fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type); + context->symbolTable.declare(*fakeVariable); + variable = fakeVariable; + } - if (variable->getType().getQualifier() == EvqConst ) { + if (variable->getType().getQualifier() == EvqConst) + { ConstantUnion* constArray = variable->getConstPointer(); TType t(variable->getType()); (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yylsp[(1) - (1)])); - } else + } + else + { (yyval.interm.intermTypedNode) = context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), (yylsp[(1) - (1)])); + } + + // don't delete $1.string, it's used by error recovery, and the pool + // pop will reclaim the memory } break; @@ -2308,8 +2618,8 @@ yyreduce: { ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setFConst((yyvsp[(1) - (1)].lex).f); - (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)])); + unionArray->setUConst((yyvsp[(1) - (1)].lex).u); + (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtUInt, EbpUndefined, EvqConst), (yylsp[(1) - (1)])); } break; @@ -2317,144 +2627,61 @@ yyreduce: { ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setBConst((yyvsp[(1) - (1)].lex).b); - (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(1) - (1)])); + unionArray->setFConst((yyvsp[(1) - (1)].lex).f); + (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)])); } break; case 9: { - (yyval.interm.intermTypedNode) = (yyvsp[(2) - (3)].interm.intermTypedNode); + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setBConst((yyvsp[(1) - (1)].lex).b); + (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(1) - (1)])); } break; case 10: { - (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); + (yyval.interm.intermTypedNode) = (yyvsp[(2) - (3)].interm.intermTypedNode); } break; case 11: { - (yyval.interm.intermTypedNode) = context->addIndexExpression((yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; case 12: { - (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); + (yyval.interm.intermTypedNode) = context->addIndexExpression((yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode)); } break; case 13: { - if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) { - context->error((yylsp[(3) - (3)]), "cannot apply dot operator to an array", "."); - context->recover(); - } - - if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isVector()) { - TVectorFields fields; - if (! context->parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yylsp[(3) - (3)]))) { - fields.num = 1; - fields.offsets[0] = 0; - context->recover(); - } + (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); + } + break; - if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { // constant folding for vector fields - (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(3) - (3)])); - if ((yyval.interm.intermTypedNode) == 0) { - context->recover(); - (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); - } - else - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqConst, (int) (*(yyvsp[(3) - (3)].lex).string).size())); - } else { - TString vectorString = *(yyvsp[(3) - (3)].lex).string; - TIntermTyped* index = context->intermediate.addSwizzle(fields, (yylsp[(3) - (3)])); - (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)])); - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (int) vectorString.size())); - } - } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isMatrix()) { - TMatrixFields fields; - if (! context->parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yylsp[(3) - (3)]))) { - fields.wholeRow = false; - fields.wholeCol = false; - fields.row = 0; - fields.col = 0; - context->recover(); - } + case 14: - if (fields.wholeRow || fields.wholeCol) { - context->error((yylsp[(2) - (3)]), " non-scalar fields not implemented yet", "."); - context->recover(); - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(0); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(3) - (3)])); - (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)])); - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(),EvqTemporary, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize())); - } else { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(fields.col * (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize() + fields.row); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(3) - (3)])); - (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)])); - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision())); - } - } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType() == EbtStruct) { - bool fieldFound = false; - const TFieldList& fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct()->fields(); - unsigned int i; - for (i = 0; i < fields.size(); ++i) { - if (fields[i]->name() == *(yyvsp[(3) - (3)].lex).string) { - fieldFound = true; - break; - } - } - if (fieldFound) { - if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { - (yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); - if ((yyval.interm.intermTypedNode) == 0) { - context->recover(); - (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); - } - else { - (yyval.interm.intermTypedNode)->setType(*fields[i]->type()); - // change the qualifier of the return type, not of the structure field - // as the structure definition is shared between various structures. - (yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst); - } - } else { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), (yylsp[(3) - (3)])); - (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)])); - (yyval.interm.intermTypedNode)->setType(*fields[i]->type()); - } - } else { - context->error((yylsp[(2) - (3)]), " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str()); - context->recover(); - (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); - } - } else { - context->error((yylsp[(2) - (3)]), " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str()); - context->recover(); - (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); - } - // don't delete $3.string, it's from the pool + { + (yyval.interm.intermTypedNode) = context->addFieldSelectionExpression((yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yylsp[(3) - (3)])); } break; - case 14: + case 15: { if (context->lValueErrorCheck((yylsp[(2) - (2)]), "++", (yyvsp[(1) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)])); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yylsp[(2) - (2)]), "++", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2463,12 +2690,12 @@ yyreduce: } break; - case 15: + case 16: { if (context->lValueErrorCheck((yylsp[(2) - (2)]), "--", (yyvsp[(1) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)])); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yylsp[(2) - (2)]), "--", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2477,7 +2704,7 @@ yyreduce: } break; - case 16: + case 17: { if (context->integerErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode), "[]")) @@ -2486,7 +2713,7 @@ yyreduce: } break; - case 17: + case 18: { TFunction* fnCall = (yyvsp[(1) - (1)].interm).function; @@ -2520,7 +2747,7 @@ yyreduce: // const TFunction* fnCandidate; bool builtIn; - fnCandidate = context->findFunction((yylsp[(1) - (1)]), fnCall, &builtIn); + fnCandidate = context->findFunction((yylsp[(1) - (1)]), fnCall, context->shaderVersion, &builtIn); if (fnCandidate) { // // A declared function. @@ -2538,7 +2765,7 @@ yyreduce: // // Treat it like a built-in unary operator. // - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, (yylsp[(1) - (1)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, (yylsp[(1) - (1)])); if ((yyval.interm.intermTypedNode) == 0) { std::stringstream extraInfoStream; extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString(); @@ -2587,14 +2814,14 @@ yyreduce: } break; - case 18: + case 19: { (yyval.interm) = (yyvsp[(1) - (1)].interm); } break; - case 19: + case 20: { context->error((yylsp[(3) - (3)]), "methods are not supported", ""); @@ -2603,21 +2830,21 @@ yyreduce: } break; - case 20: + case 21: { (yyval.interm) = (yyvsp[(1) - (2)].interm); } break; - case 21: + case 22: { (yyval.interm) = (yyvsp[(1) - (2)].interm); } break; - case 22: + case 23: { (yyval.interm).function = (yyvsp[(1) - (2)].interm.function); @@ -2625,7 +2852,7 @@ yyreduce: } break; - case 23: + case 24: { (yyval.interm).function = (yyvsp[(1) - (1)].interm.function); @@ -2633,7 +2860,7 @@ yyreduce: } break; - case 24: + case 25: { TParameter param = { 0, new TType((yyvsp[(2) - (2)].interm.intermTypedNode)->getType()) }; @@ -2643,7 +2870,7 @@ yyreduce: } break; - case 25: + case 26: { TParameter param = { 0, new TType((yyvsp[(3) - (3)].interm.intermTypedNode)->getType()) }; @@ -2653,73 +2880,21 @@ yyreduce: } break; - case 26: + case 27: { (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function); } break; - case 27: + case 28: { - // - // Constructor - // - TOperator op = EOpNull; - if ((yyvsp[(1) - (1)].interm.type).userDef) { - op = EOpConstructStruct; - } else { - switch ((yyvsp[(1) - (1)].interm.type).type) { - case EbtFloat: - if ((yyvsp[(1) - (1)].interm.type).matrix) { - switch((yyvsp[(1) - (1)].interm.type).size) { - case 2: op = EOpConstructMat2; break; - case 3: op = EOpConstructMat3; break; - case 4: op = EOpConstructMat4; break; - } - } else { - switch((yyvsp[(1) - (1)].interm.type).size) { - case 1: op = EOpConstructFloat; break; - case 2: op = EOpConstructVec2; break; - case 3: op = EOpConstructVec3; break; - case 4: op = EOpConstructVec4; break; - } - } - break; - case EbtInt: - switch((yyvsp[(1) - (1)].interm.type).size) { - case 1: op = EOpConstructInt; break; - case 2: op = EOpConstructIVec2; break; - case 3: op = EOpConstructIVec3; break; - case 4: op = EOpConstructIVec4; break; - } - break; - case EbtBool: - switch((yyvsp[(1) - (1)].interm.type).size) { - case 1: op = EOpConstructBool; break; - case 2: op = EOpConstructBVec2; break; - case 3: op = EOpConstructBVec3; break; - case 4: op = EOpConstructBVec4; break; - } - break; - default: break; - } - if (op == EOpNull) { - context->error((yylsp[(1) - (1)]), "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type)); - context->recover(); - (yyvsp[(1) - (1)].interm.type).type = EbtFloat; - op = EOpConstructFloat; - } - } - TString tempString; - TType type((yyvsp[(1) - (1)].interm.type)); - TFunction *function = new TFunction(&tempString, type, op); - (yyval.interm.function) = function; + (yyval.interm.function) = context->addConstructorFunc((yyvsp[(1) - (1)].interm.type)); } break; - case 28: + case 29: { if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string)) @@ -2730,19 +2905,19 @@ yyreduce: } break; - case 29: + case 30: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 30: + case 31: { if (context->lValueErrorCheck((yylsp[(1) - (2)]), "++", (yyvsp[(2) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)])); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yylsp[(1) - (2)]), "++", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2751,12 +2926,12 @@ yyreduce: } break; - case 31: + case 32: { if (context->lValueErrorCheck((yylsp[(1) - (2)]), "--", (yyvsp[(2) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)])); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yylsp[(1) - (2)]), "--", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2765,11 +2940,11 @@ yyreduce: } break; - case 32: + case 33: { if ((yyvsp[(1) - (2)].interm).op != EOpNull) { - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)])); if ((yyval.interm.intermTypedNode) == 0) { const char* errorOp = ""; switch((yyvsp[(1) - (2)].interm).op) { @@ -2786,30 +2961,30 @@ yyreduce: } break; - case 33: + case 34: { (yyval.interm).op = EOpNull; } break; - case 34: + case 35: { (yyval.interm).op = EOpNegative; } break; - case 35: + case 36: { (yyval.interm).op = EOpLogicalNot; } break; - case 36: + case 37: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 37: + case 38: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "*", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2818,10 +2993,10 @@ yyreduce: } break; - case 38: + case 39: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "/", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2830,15 +3005,15 @@ yyreduce: } break; - case 39: + case 40: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 40: + case 41: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "+", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2847,10 +3022,10 @@ yyreduce: } break; - case 41: + case 42: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "-", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2859,20 +3034,20 @@ yyreduce: } break; - case 42: + case 43: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 43: + case 44: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 44: + case 45: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "<", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2883,10 +3058,10 @@ yyreduce: } break; - case 45: + case 46: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), ">", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2897,10 +3072,10 @@ yyreduce: } break; - case 46: + case 47: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "<=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2911,10 +3086,10 @@ yyreduce: } break; - case 47: + case 48: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), ">=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2925,15 +3100,15 @@ yyreduce: } break; - case 48: + case 49: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 49: + case 50: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "==", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2944,10 +3119,10 @@ yyreduce: } break; - case 50: + case 51: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "!=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2958,11 +3133,6 @@ yyreduce: } break; - case 51: - - { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } - break; - case 52: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } @@ -2980,8 +3150,13 @@ yyreduce: case 55: + { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } + break; + + case 56: + { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "&&", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2992,15 +3167,15 @@ yyreduce: } break; - case 56: + case 57: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 57: + case 58: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "^^", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -3011,15 +3186,15 @@ yyreduce: } break; - case 58: + case 59: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 59: + case 60: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yylsp[(2) - (3)]), "||", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -3030,12 +3205,12 @@ yyreduce: } break; - case 60: + case 61: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 61: + case 62: { if (context->boolErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.intermTypedNode))) @@ -3053,12 +3228,12 @@ yyreduce: } break; - case 62: + case 63: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 63: + case 64: { if (context->lValueErrorCheck((yylsp[(2) - (3)]), "assign", (yyvsp[(1) - (3)].interm.intermTypedNode))) @@ -3072,39 +3247,39 @@ yyreduce: } break; - case 64: + case 65: { (yyval.interm).op = EOpAssign; } break; - case 65: + case 66: { (yyval.interm).op = EOpMulAssign; } break; - case 66: + case 67: { (yyval.interm).op = EOpDivAssign; } break; - case 67: + case 68: { (yyval.interm).op = EOpAddAssign; } break; - case 68: + case 69: { (yyval.interm).op = EOpSubAssign; } break; - case 69: + case 70: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 70: + case 71: { (yyval.interm.intermTypedNode) = context->intermediate.addComma((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)])); @@ -3116,7 +3291,7 @@ yyreduce: } break; - case 71: + case 72: { if (context->constErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode))) @@ -3125,7 +3300,16 @@ yyreduce: } break; - case 72: + case 73: + + { + if (context->enterStructDeclaration((yylsp[(1) - (2)]), *(yyvsp[(1) - (2)].lex).string)) + context->recover(); + (yyval.lex) = (yyvsp[(1) - (2)].lex); + } + break; + + case 74: { TFunction &function = *((yyvsp[(1) - (2)].interm).function); @@ -3156,7 +3340,7 @@ yyreduce: } break; - case 73: + case 75: { if ((yyvsp[(1) - (2)].interm).intermAggregate) @@ -3165,7 +3349,7 @@ yyreduce: } break; - case 74: + case 76: { if (((yyvsp[(2) - (4)].interm.precision) == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { @@ -3180,7 +3364,39 @@ yyreduce: } break; - case 75: + case 77: + + { + ES3_ONLY(getQualifierString((yyvsp[(1) - (5)].interm.type).qualifier), (yylsp[(1) - (5)]), "interface blocks"); + (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (5)].interm.type), (yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(3) - (5)].interm.fieldList), NULL, (yyloc), NULL, (yyloc)); + } + break; + + case 78: + + { + ES3_ONLY(getQualifierString((yyvsp[(1) - (6)].interm.type).qualifier), (yylsp[(1) - (6)]), "interface blocks"); + (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (6)].interm.type), (yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string, (yyvsp[(3) - (6)].interm.fieldList), (yyvsp[(5) - (6)].lex).string, (yylsp[(5) - (6)]), NULL, (yyloc)); + } + break; + + case 79: + + { + ES3_ONLY(getQualifierString((yyvsp[(1) - (9)].interm.type).qualifier), (yylsp[(1) - (9)]), "interface blocks"); + (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[(1) - (9)].interm.type), (yylsp[(2) - (9)]), *(yyvsp[(2) - (9)].lex).string, (yyvsp[(3) - (9)].interm.fieldList), (yyvsp[(5) - (9)].lex).string, (yylsp[(5) - (9)]), (yyvsp[(7) - (9)].interm.intermTypedNode), (yylsp[(6) - (9)])); + } + break; + + case 80: + + { + context->parseGlobalLayoutQualifier((yyvsp[(1) - (2)].interm.type)); + (yyval.interm.intermNode) = 0; + } + break; + + case 81: { // @@ -3191,7 +3407,7 @@ yyreduce: // // Redeclarations are allowed. But, return types and parameter qualifiers must match. // - TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName())); + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName(), context->shaderVersion)); if (prevDec) { if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) { context->error((yylsp[(2) - (2)]), "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString()); @@ -3208,7 +3424,7 @@ yyreduce: // // Check for previously declared variables using the same name. // - TSymbol *prevSym = context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getName()); + TSymbol *prevSym = context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getName(), context->shaderVersion); if (prevSym) { if (!prevSym->isFunction()) @@ -3236,21 +3452,21 @@ yyreduce: } break; - case 76: + case 82: { (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function); } break; - case 77: + case 83: { (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function); } break; - case 78: + case 84: { // Add the parameter @@ -3262,7 +3478,7 @@ yyreduce: } break; - case 79: + case 85: { // @@ -3284,7 +3500,7 @@ yyreduce: } break; - case 80: + case 86: { if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) { @@ -3305,7 +3521,7 @@ yyreduce: } break; - case 81: + case 87: { if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) { @@ -3319,7 +3535,7 @@ yyreduce: } break; - case 82: + case 88: { // Check that we can make an array out of this type @@ -3340,16 +3556,16 @@ yyreduce: } break; - case 83: + case 89: { (yyval.interm) = (yyvsp[(3) - (3)].interm); - if (context->paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type)) + if (context->paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.qualifier), (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type)) context->recover(); } break; - case 84: + case 90: { (yyval.interm) = (yyvsp[(2) - (2)].interm); @@ -3360,16 +3576,16 @@ yyreduce: } break; - case 85: + case 91: { (yyval.interm) = (yyvsp[(3) - (3)].interm); - if (context->paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type)) + if (context->paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.qualifier), (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type)) context->recover(); } break; - case 86: + case 92: { (yyval.interm) = (yyvsp[(2) - (2)].interm); @@ -3380,35 +3596,35 @@ yyreduce: } break; - case 87: + case 93: { (yyval.interm.qualifier) = EvqIn; } break; - case 88: + case 94: { (yyval.interm.qualifier) = EvqIn; } break; - case 89: + case 95: { (yyval.interm.qualifier) = EvqOut; } break; - case 90: + case 96: { (yyval.interm.qualifier) = EvqInOut; } break; - case 91: + case 97: { TParameter param = { 0, new TType((yyvsp[(1) - (1)].interm.type)) }; @@ -3416,216 +3632,89 @@ yyreduce: } break; - case 92: + case 98: { (yyval.interm) = (yyvsp[(1) - (1)].interm); } break; - case 93: + case 99: { - if ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant && !(yyvsp[(3) - (3)].lex).symbol) - { - context->error((yylsp[(3) - (3)]), "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str()); - context->recover(); - } - - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yylsp[(3) - (3)])); - (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, symbol, (yylsp[(3) - (3)])); - - if (context->structQualifierErrorCheck((yylsp[(3) - (3)]), (yyval.interm).type)) - context->recover(); - - if (context->nonInitConstErrorCheck((yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, false)) - context->recover(); - - TVariable* variable = 0; - if (context->nonInitErrorCheck((yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, variable)) - context->recover(); - if (symbol && variable) - symbol->setId(variable->getUniqueId()); + (yyval.interm) = (yyvsp[(1) - (3)].interm); + (yyval.interm).intermAggregate = context->parseDeclarator((yyval.interm).type, (yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].lex).symbol, (yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string); } break; - case 94: + case 100: { - if (context->structQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm).type)) - context->recover(); - - if (context->nonInitConstErrorCheck((yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, true)) - context->recover(); - (yyval.interm) = (yyvsp[(1) - (5)].interm); - - if (context->arrayTypeErrorCheck((yylsp[(4) - (5)]), (yyvsp[(1) - (5)].interm).type) || context->arrayQualifierErrorCheck((yylsp[(4) - (5)]), (yyvsp[(1) - (5)].interm).type)) - context->recover(); - else { - (yyvsp[(1) - (5)].interm).type.setArray(true); - TVariable* variable; - if (context->arrayErrorCheck((yylsp[(4) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, variable)) - context->recover(); - } + context->parseArrayDeclarator((yyval.interm).type, (yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yylsp[(4) - (5)]), NULL, NULL); } break; - case 95: + case 101: { - if (context->structQualifierErrorCheck((yylsp[(3) - (6)]), (yyvsp[(1) - (6)].interm).type)) - context->recover(); - - if (context->nonInitConstErrorCheck((yylsp[(3) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, true)) - context->recover(); - (yyval.interm) = (yyvsp[(1) - (6)].interm); - - if (context->arrayTypeErrorCheck((yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).type) || context->arrayQualifierErrorCheck((yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).type)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck((yylsp[(4) - (6)]), (yyvsp[(5) - (6)].interm.intermTypedNode), size)) - context->recover(); - (yyvsp[(1) - (6)].interm).type.setArray(true, size); - TVariable* variable = 0; - if (context->arrayErrorCheck((yylsp[(4) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable)) - context->recover(); - TType type = TType((yyvsp[(1) - (6)].interm).type); - type.setArraySize(size); - (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *(yyvsp[(3) - (6)].lex).string, type, (yylsp[(3) - (6)])), (yylsp[(3) - (6)])); - } + (yyval.interm).intermAggregate = context->parseArrayDeclarator((yyval.interm).type, (yylsp[(3) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).intermNode, (yyvsp[(5) - (6)].interm.intermTypedNode)); } break; - case 96: + case 102: { - if (context->structQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm).type)) - context->recover(); - (yyval.interm) = (yyvsp[(1) - (5)].interm); - - TIntermNode* intermNode; - if (!context->executeInitializer((yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, (yyvsp[(5) - (5)].interm.intermTypedNode), intermNode)) { - // - // build the intermediate representation - // - if (intermNode) - (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (5)].interm).intermNode, intermNode, (yylsp[(4) - (5)])); - else - (yyval.interm).intermAggregate = (yyvsp[(1) - (5)].interm).intermAggregate; - } else { - context->recover(); - (yyval.interm).intermAggregate = 0; - } + (yyval.interm).intermAggregate = context->parseInitDeclarator((yyval.interm).type, (yyvsp[(1) - (5)].interm).intermAggregate, (yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yylsp[(4) - (5)]), (yyvsp[(5) - (5)].interm.intermTypedNode)); } break; - case 97: + case 103: { (yyval.interm).type = (yyvsp[(1) - (1)].interm.type); - (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType((yyvsp[(1) - (1)].interm.type)), (yylsp[(1) - (1)])), (yylsp[(1) - (1)])); + (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[(1) - (1)]), ""); } break; - case 98: + case 104: { - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yylsp[(2) - (2)])); - (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (2)])); - - if (context->structQualifierErrorCheck((yylsp[(2) - (2)]), (yyval.interm).type)) - context->recover(); - - if (context->nonInitConstErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, false)) - context->recover(); - - (yyval.interm).type = (yyvsp[(1) - (2)].interm.type); - - TVariable* variable = 0; - if (context->nonInitErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, variable)) - context->recover(); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); + (yyval.interm).type = (yyvsp[(1) - (2)].interm.type); + (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string); } break; - case 99: + case 105: { context->error((yylsp[(2) - (4)]), "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str()); context->recover(); - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yylsp[(2) - (4)])); - (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (4)])); (yyval.interm).type = (yyvsp[(1) - (4)].interm.type); + (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string); } break; - case 100: + case 106: { - TType type = TType((yyvsp[(1) - (5)].interm.type)); - int size; - if (context->arraySizeErrorCheck((yylsp[(2) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size)) - context->recover(); - type.setArraySize(size); - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yylsp[(2) - (5)])); - (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (5)])); - - if (context->structQualifierErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.type))) - context->recover(); - - if (context->nonInitConstErrorCheck((yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), true)) - context->recover(); - (yyval.interm).type = (yyvsp[(1) - (5)].interm.type); - - if (context->arrayTypeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)) || context->arrayQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type))) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size)) - context->recover(); - - (yyvsp[(1) - (5)].interm.type).setArray(true, size); - TVariable* variable = 0; - if (context->arrayErrorCheck((yylsp[(3) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable)) - context->recover(); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); - } + (yyval.interm).intermAggregate = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yylsp[(3) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode)); } break; - case 101: + case 107: { - if (context->structQualifierErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type))) - context->recover(); - (yyval.interm).type = (yyvsp[(1) - (4)].interm.type); - - TIntermNode* intermNode; - if (!context->executeInitializer((yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode)) { - // - // Build intermediate representation - // - if(intermNode) - (yyval.interm).intermAggregate = context->intermediate.makeAggregate(intermNode, (yylsp[(3) - (4)])); - else - (yyval.interm).intermAggregate = 0; - } else { - context->recover(); - (yyval.interm).intermAggregate = 0; - } + (yyval.interm).intermAggregate = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string, (yylsp[(3) - (4)]), (yyvsp[(4) - (4)].interm.intermTypedNode)); } break; - case 102: + case 108: { VERTEX_ONLY("invariant declaration", (yylsp[(1) - (2)])); @@ -3647,7 +3736,7 @@ yyreduce: } break; - case 103: + case 109: { (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); @@ -3660,50 +3749,49 @@ yyreduce: } break; - case 104: + case 110: { - if ((yyvsp[(2) - (2)].interm.type).array) { - context->error((yylsp[(2) - (2)]), "not supported", "first-class array"); - context->recover(); - (yyvsp[(2) - (2)].interm.type).setArray(false); - } + (yyval.interm.type) = context->addFullySpecifiedType((yyvsp[(1) - (2)].interm.type).qualifier, (yyvsp[(1) - (2)].interm.type).layoutQualifier, (yyvsp[(2) - (2)].interm.type)); + } + break; - if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute && - ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) { - context->error((yylsp[(2) - (2)]), "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier)); - context->recover(); - } - if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) && - ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) { - context->error((yylsp[(2) - (2)]), "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier)); - context->recover(); - } - (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type); - (yyval.interm.type).qualifier = (yyvsp[(1) - (2)].interm.type).qualifier; + case 111: + + { + (yyval.interm.type).qualifier = EvqSmooth; } break; - case 105: + case 112: { - (yyval.interm.type).setBasic(EbtVoid, EvqConst, (yylsp[(1) - (1)])); + (yyval.interm.type).qualifier = EvqFlat; } break; - case 106: + case 113: + + { + (yyval.interm.qualifier) = EvqConst; + } + break; + + case 114: { VERTEX_ONLY("attribute", (yylsp[(1) - (1)])); + ES2_ONLY("attribute", (yylsp[(1) - (1)])); if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "attribute")) context->recover(); (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yylsp[(1) - (1)])); } break; - case 107: + case 115: { + ES2_ONLY("varying", (yylsp[(1) - (1)])); if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "varying")) context->recover(); if (context->shaderType == SH_VERTEX_SHADER) @@ -3713,9 +3801,10 @@ yyreduce: } break; - case 108: + case 116: { + ES2_ONLY("varying", (yylsp[(1) - (2)])); if (context->globalErrorCheck((yylsp[(1) - (2)]), context->symbolTable.atGlobalLevel(), "invariant varying")) context->recover(); if (context->shaderType == SH_VERTEX_SHADER) @@ -3725,16 +3814,111 @@ yyreduce: } break; - case 109: + case 117: + + { + if ((yyvsp[(1) - (1)].interm.type).qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { + context->error((yylsp[(1) - (1)]), "Local variables can only use the const storage qualifier.", getQualifierString((yyvsp[(1) - (1)].interm.type).qualifier)); + context->recover(); + } else { + (yyval.interm.type).setBasic(EbtVoid, (yyvsp[(1) - (1)].interm.type).qualifier, (yylsp[(1) - (1)])); + } + } + break; + + case 118: + + { + (yyval.interm.type) = context->joinInterpolationQualifiers((yylsp[(1) - (2)]), (yyvsp[(1) - (2)].interm.type).qualifier, (yylsp[(2) - (2)]), (yyvsp[(2) - (2)].interm.type).qualifier); + } + break; + + case 119: + + { + context->error((yylsp[(1) - (1)]), "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString((yyvsp[(1) - (1)].interm.type).qualifier)); + context->recover(); + + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[(1) - (1)])); + } + break; + + case 120: + + { + (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).layoutQualifier = (yyvsp[(1) - (1)].interm.layoutQualifier); + } + break; + + case 121: + + { + (yyval.interm.type).setBasic(EbtVoid, (yyvsp[(2) - (2)].interm.type).qualifier, (yylsp[(2) - (2)])); + (yyval.interm.type).layoutQualifier = (yyvsp[(1) - (2)].interm.layoutQualifier); + } + break; + + case 122: + + { + (yyval.interm.type).qualifier = EvqConst; + } + break; + + case 123: + + { + ES3_ONLY("in", (yylsp[(1) - (1)]), "storage qualifier"); + (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + } + break; + + case 124: + + { + ES3_ONLY("out", (yylsp[(1) - (1)]), "storage qualifier"); + (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + } + break; + + case 125: + + { + ES3_ONLY("centroid in", (yylsp[(1) - (2)]), "storage qualifier"); + if (context->shaderType == SH_VERTEX_SHADER) + { + context->error((yylsp[(1) - (2)]), "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); + context->recover(); + } + (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + } + break; + + case 126: + + { + ES3_ONLY("centroid out", (yylsp[(1) - (2)]), "storage qualifier"); + if (context->shaderType == SH_FRAGMENT_SHADER) + { + context->error((yylsp[(1) - (2)]), "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); + context->recover(); + } + (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + } + break; + + case 127: { if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "uniform")) context->recover(); - (yyval.interm.type).setBasic(EbtVoid, EvqUniform, (yylsp[(1) - (1)])); + (yyval.interm.type).qualifier = EvqUniform; } break; - case 110: + case 128: { (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); @@ -3748,43 +3932,91 @@ yyreduce: } break; - case 111: + case 129: { (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type); (yyval.interm.type).precision = (yyvsp[(1) - (2)].interm.precision); + + if (!SupportsPrecision((yyvsp[(2) - (2)].interm.type).type)) { + context->error((yylsp[(1) - (2)]), "illegal type for precision qualifier", getBasicString((yyvsp[(2) - (2)].interm.type).type)); + context->recover(); + } } break; - case 112: + case 130: { (yyval.interm.precision) = EbpHigh; } break; - case 113: + case 131: { (yyval.interm.precision) = EbpMedium; } break; - case 114: + case 132: { (yyval.interm.precision) = EbpLow; } break; - case 115: + case 133: + + { + ES3_ONLY("layout", (yylsp[(1) - (4)]), "qualifier"); + (yyval.interm.layoutQualifier) = (yyvsp[(3) - (4)].interm.layoutQualifier); + } + break; + + case 134: + + { + (yyval.interm.layoutQualifier) = (yyvsp[(1) - (1)].interm.layoutQualifier); + } + break; + + case 135: + + { + (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[(1) - (3)].interm.layoutQualifier), (yyvsp[(3) - (3)].interm.layoutQualifier)); + } + break; + + case 136: + + { + (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[(1) - (1)].lex).string, (yylsp[(1) - (1)])); + } + break; + + case 137: + + { + (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[(1) - (3)].lex).string, (yylsp[(1) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyvsp[(3) - (3)].lex).i, (yylsp[(3) - (3)])); + } + break; + + case 138: + + { + (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[(1) - (3)].lex).string, (yylsp[(1) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyvsp[(3) - (3)].lex).i, (yylsp[(3) - (3)])); + } + break; + + case 139: { (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); } break; - case 116: + case 140: { (yyval.interm.type) = (yyvsp[(1) - (4)].interm.type); @@ -3800,7 +4032,7 @@ yyreduce: } break; - case 117: + case 141: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3808,7 +4040,7 @@ yyreduce: } break; - case 118: + case 142: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3816,7 +4048,7 @@ yyreduce: } break; - case 119: + case 143: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3824,7 +4056,15 @@ yyreduce: } break; - case 120: + case 144: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[(1) - (1)])); + } + break; + + case 145: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3832,7 +4072,7 @@ yyreduce: } break; - case 121: + case 146: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3841,7 +4081,7 @@ yyreduce: } break; - case 122: + case 147: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3850,7 +4090,7 @@ yyreduce: } break; - case 123: + case 148: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3859,7 +4099,7 @@ yyreduce: } break; - case 124: + case 149: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3868,7 +4108,7 @@ yyreduce: } break; - case 125: + case 150: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3877,7 +4117,7 @@ yyreduce: } break; - case 126: + case 151: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3886,7 +4126,7 @@ yyreduce: } break; - case 127: + case 152: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3895,7 +4135,7 @@ yyreduce: } break; - case 128: + case 153: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3904,7 +4144,7 @@ yyreduce: } break; - case 129: + case 154: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3913,34 +4153,115 @@ yyreduce: } break; - case 130: + case 155: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setAggregate(2); + } + break; + + case 156: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setAggregate(3); + } + break; + + case 157: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setAggregate(4); + } + break; + + case 158: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); - (yyval.interm.type).setAggregate(2, true); + (yyval.interm.type).setMatrix(2, 2); } break; - case 131: + case 159: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); - (yyval.interm.type).setAggregate(3, true); + (yyval.interm.type).setMatrix(3, 3); } break; - case 132: + case 160: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); - (yyval.interm.type).setAggregate(4, true); + (yyval.interm.type).setMatrix(4, 4); } break; - case 133: + case 161: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setMatrix(2, 3); + } + break; + + case 162: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setMatrix(3, 2); + } + break; + + case 163: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setMatrix(2, 4); + } + break; + + case 164: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setMatrix(4, 2); + } + break; + + case 165: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setMatrix(3, 4); + } + break; + + case 166: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)])); + (yyval.interm.type).setMatrix(4, 3); + } + break; + + case 167: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3948,7 +4269,15 @@ yyreduce: } break; - case 134: + case 168: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSampler3D, qual, (yylsp[(1) - (1)])); + } + break; + + case 169: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3956,7 +4285,103 @@ yyreduce: } break; - case 135: + case 170: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSampler2DArray, qual, (yylsp[(1) - (1)])); + } + break; + + case 171: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtISampler2D, qual, (yylsp[(1) - (1)])); + } + break; + + case 172: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtISampler3D, qual, (yylsp[(1) - (1)])); + } + break; + + case 173: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtISamplerCube, qual, (yylsp[(1) - (1)])); + } + break; + + case 174: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtISampler2DArray, qual, (yylsp[(1) - (1)])); + } + break; + + case 175: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUSampler2D, qual, (yylsp[(1) - (1)])); + } + break; + + case 176: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUSampler3D, qual, (yylsp[(1) - (1)])); + } + break; + + case 177: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUSamplerCube, qual, (yylsp[(1) - (1)])); + } + break; + + case 178: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtUSampler2DArray, qual, (yylsp[(1) - (1)])); + } + break; + + case 179: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSampler2DShadow, qual, (yylsp[(1) - (1)])); + } + break; + + case 180: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSamplerCubeShadow, qual, (yylsp[(1) - (1)])); + } + break; + + case 181: + + { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSampler2DArrayShadow, qual, (yylsp[(1) - (1)])); + } + break; + + case 182: { if (!context->supportsExtension("GL_OES_EGL_image_external")) { @@ -3968,7 +4393,7 @@ yyreduce: } break; - case 136: + case 183: { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { @@ -3980,7 +4405,7 @@ yyreduce: } break; - case 137: + case 184: { (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); @@ -3988,7 +4413,7 @@ yyreduce: } break; - case 138: + case 185: { // @@ -4002,52 +4427,38 @@ yyreduce: } break; - case 139: + case 186: { if (context->enterStructDeclaration((yylsp[(2) - (3)]), *(yyvsp[(2) - (3)].lex).string)) context->recover(); } break; - case 140: + case 187: { - if (context->reservedErrorCheck((yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string)) - context->recover(); - - TType* structure = new TType(new TStructure((yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.fieldList))); - TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].lex).string, *structure, true); - if (! context->symbolTable.insert(*userTypeDef)) { - context->error((yylsp[(2) - (6)]), "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct"); - context->recover(); - } - (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (6)])); - (yyval.interm.type).userDef = structure; - context->exitStructDeclaration(); + (yyval.interm.type) = context->addStructure((yylsp[(1) - (6)]), (yylsp[(2) - (6)]), (yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.fieldList)); } break; - case 141: + case 188: { if (context->enterStructDeclaration((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string)) context->recover(); } break; - case 142: + case 189: { - TType* structure = new TType(new TStructure(NewPoolTString(""), (yyvsp[(4) - (5)].interm.fieldList))); - (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (5)])); - (yyval.interm.type).userDef = structure; - context->exitStructDeclaration(); + (yyval.interm.type) = context->addStructure((yylsp[(1) - (5)]), (yyloc), NewPoolTString(""), (yyvsp[(4) - (5)].interm.fieldList)); } break; - case 143: + case 190: { (yyval.interm.fieldList) = (yyvsp[(1) - (1)].interm.fieldList); } break; - case 144: + case 191: { (yyval.interm.fieldList) = (yyvsp[(1) - (2)].interm.fieldList); @@ -4064,41 +4475,24 @@ yyreduce: } break; - case 145: + case 192: { - (yyval.interm.fieldList) = (yyvsp[(2) - (3)].interm.fieldList); + (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[(1) - (3)].interm.type), (yyvsp[(2) - (3)].interm.fieldList)); + } + break; - if (context->voidErrorCheck((yylsp[(1) - (3)]), (*(yyvsp[(2) - (3)].interm.fieldList))[0]->name(), (yyvsp[(1) - (3)].interm.type))) { - context->recover(); - } - for (unsigned int i = 0; i < (yyval.interm.fieldList)->size(); ++i) { - // - // Careful not to replace already known aspects of type, like array-ness - // - TType* type = (*(yyval.interm.fieldList))[i]->type(); - type->setBasicType((yyvsp[(1) - (3)].interm.type).type); - type->setNominalSize((yyvsp[(1) - (3)].interm.type).size); - type->setMatrix((yyvsp[(1) - (3)].interm.type).matrix); - type->setPrecision((yyvsp[(1) - (3)].interm.type).precision); - - // don't allow arrays of arrays - if (type->isArray()) { - if (context->arrayTypeErrorCheck((yylsp[(1) - (3)]), (yyvsp[(1) - (3)].interm.type))) - context->recover(); - } - if ((yyvsp[(1) - (3)].interm.type).array) - type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize); - if ((yyvsp[(1) - (3)].interm.type).userDef) - type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct()); + case 193: - if (context->structNestingErrorCheck((yylsp[(1) - (3)]), *(*(yyval.interm.fieldList))[i])) - context->recover(); - } + { + // ES3 Only, but errors should be handled elsewhere + (yyvsp[(2) - (4)].interm.type).qualifier = (yyvsp[(1) - (4)].interm.type).qualifier; + (yyvsp[(2) - (4)].interm.type).layoutQualifier = (yyvsp[(1) - (4)].interm.type).layoutQualifier; + (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[(2) - (4)].interm.type), (yyvsp[(3) - (4)].interm.fieldList)); } break; - case 146: + case 194: { (yyval.interm.fieldList) = NewPoolTFieldList(); @@ -4106,101 +4500,101 @@ yyreduce: } break; - case 147: + case 195: { (yyval.interm.fieldList)->push_back((yyvsp[(3) - (3)].interm.field)); } break; - case 148: + case 196: { if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string)) context->recover(); TType* type = new TType(EbtVoid, EbpUndefined); - (yyval.interm.field) = new TField(type, (yyvsp[(1) - (1)].lex).string); + (yyval.interm.field) = new TField(type, (yyvsp[(1) - (1)].lex).string, (yylsp[(1) - (1)])); } break; - case 149: + case 197: { if (context->reservedErrorCheck((yylsp[(1) - (4)]), *(yyvsp[(1) - (4)].lex).string)) context->recover(); TType* type = new TType(EbtVoid, EbpUndefined); - int size = 0; + int size; if (context->arraySizeErrorCheck((yylsp[(3) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size)) context->recover(); type->setArraySize(size); - (yyval.interm.field) = new TField(type, (yyvsp[(1) - (4)].lex).string); + (yyval.interm.field) = new TField(type, (yyvsp[(1) - (4)].lex).string, (yylsp[(1) - (4)])); } break; - case 150: + case 198: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 151: + case 199: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 152: + case 200: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); } break; - case 153: + case 201: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 154: + case 202: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 155: + case 203: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 156: + case 204: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 157: + case 205: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 158: + case 206: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 159: + case 207: { (yyval.interm.intermAggregate) = 0; } break; - case 160: + case 208: { context->symbolTable.push(); } break; - case 161: + case 209: { context->symbolTable.pop(); } break; - case 162: + case 210: { if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) { @@ -4211,44 +4605,44 @@ yyreduce: } break; - case 163: + case 211: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 164: + case 212: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 165: + case 213: { context->symbolTable.push(); } break; - case 166: + case 214: { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); } break; - case 167: + case 215: { context->symbolTable.push(); } break; - case 168: + case 216: { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); } break; - case 169: + case 217: { (yyval.interm.intermNode) = 0; } break; - case 170: + case 218: { if ((yyvsp[(2) - (3)].interm.intermAggregate)) { @@ -4259,31 +4653,31 @@ yyreduce: } break; - case 171: + case 219: { (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), (yyloc)); } break; - case 172: + case 220: { (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), (yyloc)); } break; - case 173: + case 221: { (yyval.interm.intermNode) = 0; } break; - case 174: + case 222: { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[(1) - (2)].interm.intermTypedNode)); } break; - case 175: + case 223: { if (context->boolErrorCheck((yylsp[(1) - (5)]), (yyvsp[(3) - (5)].interm.intermTypedNode))) @@ -4292,7 +4686,7 @@ yyreduce: } break; - case 176: + case 224: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode); @@ -4300,7 +4694,7 @@ yyreduce: } break; - case 177: + case 225: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode); @@ -4308,7 +4702,7 @@ yyreduce: } break; - case 178: + case 226: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); @@ -4317,7 +4711,7 @@ yyreduce: } break; - case 179: + case 227: { TIntermNode* intermNode; @@ -4335,12 +4729,12 @@ yyreduce: } break; - case 180: + case 228: { context->symbolTable.push(); ++context->loopNestingLevel; } break; - case 181: + case 229: { context->symbolTable.pop(); @@ -4349,12 +4743,12 @@ yyreduce: } break; - case 182: + case 230: { ++context->loopNestingLevel; } break; - case 183: + case 231: { if (context->boolErrorCheck((yylsp[(8) - (8)]), (yyvsp[(6) - (8)].interm.intermTypedNode))) @@ -4365,12 +4759,12 @@ yyreduce: } break; - case 184: + case 232: { context->symbolTable.push(); ++context->loopNestingLevel; } break; - case 185: + case 233: { context->symbolTable.pop(); @@ -4379,35 +4773,35 @@ yyreduce: } break; - case 186: + case 234: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 187: + case 235: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 188: + case 236: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); } break; - case 189: + case 237: { (yyval.interm.intermTypedNode) = 0; } break; - case 190: + case 238: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode); @@ -4415,7 +4809,7 @@ yyreduce: } break; - case 191: + case 239: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode); @@ -4423,7 +4817,7 @@ yyreduce: } break; - case 192: + case 240: { if (context->loopNestingLevel <= 0) { @@ -4434,7 +4828,7 @@ yyreduce: } break; - case 193: + case 241: { if (context->loopNestingLevel <= 0) { @@ -4445,7 +4839,7 @@ yyreduce: } break; - case 194: + case 242: { (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yylsp[(1) - (2)])); @@ -4456,7 +4850,7 @@ yyreduce: } break; - case 195: + case 243: { (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yylsp[(1) - (3)])); @@ -4471,7 +4865,7 @@ yyreduce: } break; - case 196: + case 244: { FRAG_ONLY("discard", (yylsp[(1) - (2)])); @@ -4479,7 +4873,7 @@ yyreduce: } break; - case 197: + case 245: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); @@ -4487,7 +4881,7 @@ yyreduce: } break; - case 198: + case 246: { (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), (yyloc)); @@ -4495,26 +4889,26 @@ yyreduce: } break; - case 199: + case 247: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 200: + case 248: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); } break; - case 201: + case 249: { TFunction* function = (yyvsp[(1) - (1)].interm).function; - const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName()); + const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion); if (builtIn) { @@ -4522,7 +4916,7 @@ yyreduce: context->recover(); } - TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName())); + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName(), context->shaderVersion)); // // Note: 'prevDec' could be 'function' if this is the first time we've seen function // as it would have just been put in the symbol table. Otherwise, we're looking up @@ -4573,7 +4967,7 @@ yyreduce: // // Insert the parameters with name in the symbol table. // - if (! context->symbolTable.insert(*variable)) { + if (! context->symbolTable.declare(*variable)) { context->error((yylsp[(1) - (1)]), "redefinition", variable->getName().c_str()); context->recover(); delete variable; @@ -4585,9 +4979,8 @@ yyreduce: paramNodes = context->intermediate.growAggregate( paramNodes, context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), - (yylsp[(1) - (1)])), + variable->getName(), + variable->getType(), (yylsp[(1) - (1)])), (yylsp[(1) - (1)])); } else { paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, (yylsp[(1) - (1)])), (yylsp[(1) - (1)])); @@ -4599,7 +4992,7 @@ yyreduce: } break; - case 202: + case 250: { //?? Check that all paths return a value if return type != void ? diff --git a/chromium/third_party/angle/src/compiler/glslang_tab.h b/chromium/third_party/angle/src/compiler/translator/glslang_tab.h index 07d0b15f4ae..c6a61dcd85f 100644 --- a/chromium/third_party/angle/src/compiler/glslang_tab.h +++ b/chromium/third_party/angle/src/compiler/translator/glslang_tab.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.7. */ +/* A Bison parser, made by GNU Bison 2.7.1. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,6 @@ extern int yydebug; #define YYLTYPE TSourceLoc #define YYLTYPE_IS_DECLARED 1 -#define SH_MAX_TOKEN_LENGTH 256 // WebGL spec. @@ -65,88 +64,121 @@ extern int yydebug; BOOL_TYPE = 265, FLOAT_TYPE = 266, INT_TYPE = 267, - BREAK = 268, - CONTINUE = 269, - DO = 270, - ELSE = 271, - FOR = 272, - IF = 273, - DISCARD = 274, - RETURN = 275, - BVEC2 = 276, - BVEC3 = 277, - BVEC4 = 278, - IVEC2 = 279, - IVEC3 = 280, - IVEC4 = 281, - VEC2 = 282, - VEC3 = 283, - VEC4 = 284, - MATRIX2 = 285, - MATRIX3 = 286, - MATRIX4 = 287, - IN_QUAL = 288, - OUT_QUAL = 289, - INOUT_QUAL = 290, - UNIFORM = 291, - VARYING = 292, - STRUCT = 293, - VOID_TYPE = 294, - WHILE = 295, - SAMPLER2D = 296, - SAMPLERCUBE = 297, - SAMPLER_EXTERNAL_OES = 298, - SAMPLER2DRECT = 299, - IDENTIFIER = 300, - TYPE_NAME = 301, - FLOATCONSTANT = 302, - INTCONSTANT = 303, - BOOLCONSTANT = 304, - LEFT_OP = 305, - RIGHT_OP = 306, - INC_OP = 307, - DEC_OP = 308, - LE_OP = 309, - GE_OP = 310, - EQ_OP = 311, - NE_OP = 312, - AND_OP = 313, - OR_OP = 314, - XOR_OP = 315, - MUL_ASSIGN = 316, - DIV_ASSIGN = 317, - ADD_ASSIGN = 318, - MOD_ASSIGN = 319, - LEFT_ASSIGN = 320, - RIGHT_ASSIGN = 321, - AND_ASSIGN = 322, - XOR_ASSIGN = 323, - OR_ASSIGN = 324, - SUB_ASSIGN = 325, - LEFT_PAREN = 326, - RIGHT_PAREN = 327, - LEFT_BRACKET = 328, - RIGHT_BRACKET = 329, - LEFT_BRACE = 330, - RIGHT_BRACE = 331, - DOT = 332, - COMMA = 333, - COLON = 334, - EQUAL = 335, - SEMICOLON = 336, - BANG = 337, - DASH = 338, - TILDE = 339, - PLUS = 340, - STAR = 341, - SLASH = 342, - PERCENT = 343, - LEFT_ANGLE = 344, - RIGHT_ANGLE = 345, - VERTICAL_BAR = 346, - CARET = 347, - AMPERSAND = 348, - QUESTION = 349 + UINT_TYPE = 268, + BREAK = 269, + CONTINUE = 270, + DO = 271, + ELSE = 272, + FOR = 273, + IF = 274, + DISCARD = 275, + RETURN = 276, + SWITCH = 277, + CASE = 278, + DEFAULT = 279, + BVEC2 = 280, + BVEC3 = 281, + BVEC4 = 282, + IVEC2 = 283, + IVEC3 = 284, + IVEC4 = 285, + VEC2 = 286, + VEC3 = 287, + VEC4 = 288, + UVEC2 = 289, + UVEC3 = 290, + UVEC4 = 291, + MATRIX2 = 292, + MATRIX3 = 293, + MATRIX4 = 294, + IN_QUAL = 295, + OUT_QUAL = 296, + INOUT_QUAL = 297, + UNIFORM = 298, + VARYING = 299, + MATRIX2x3 = 300, + MATRIX3x2 = 301, + MATRIX2x4 = 302, + MATRIX4x2 = 303, + MATRIX3x4 = 304, + MATRIX4x3 = 305, + CENTROID = 306, + FLAT = 307, + SMOOTH = 308, + STRUCT = 309, + VOID_TYPE = 310, + WHILE = 311, + SAMPLER2D = 312, + SAMPLERCUBE = 313, + SAMPLER_EXTERNAL_OES = 314, + SAMPLER2DRECT = 315, + SAMPLER2DARRAY = 316, + ISAMPLER2D = 317, + ISAMPLER3D = 318, + ISAMPLERCUBE = 319, + ISAMPLER2DARRAY = 320, + USAMPLER2D = 321, + USAMPLER3D = 322, + USAMPLERCUBE = 323, + USAMPLER2DARRAY = 324, + SAMPLER3D = 325, + SAMPLER3DRECT = 326, + SAMPLER2DSHADOW = 327, + SAMPLERCUBESHADOW = 328, + SAMPLER2DARRAYSHADOW = 329, + LAYOUT = 330, + IDENTIFIER = 331, + TYPE_NAME = 332, + FLOATCONSTANT = 333, + INTCONSTANT = 334, + UINTCONSTANT = 335, + BOOLCONSTANT = 336, + FIELD_SELECTION = 337, + LEFT_OP = 338, + RIGHT_OP = 339, + INC_OP = 340, + DEC_OP = 341, + LE_OP = 342, + GE_OP = 343, + EQ_OP = 344, + NE_OP = 345, + AND_OP = 346, + OR_OP = 347, + XOR_OP = 348, + MUL_ASSIGN = 349, + DIV_ASSIGN = 350, + ADD_ASSIGN = 351, + MOD_ASSIGN = 352, + LEFT_ASSIGN = 353, + RIGHT_ASSIGN = 354, + AND_ASSIGN = 355, + XOR_ASSIGN = 356, + OR_ASSIGN = 357, + SUB_ASSIGN = 358, + LEFT_PAREN = 359, + RIGHT_PAREN = 360, + LEFT_BRACKET = 361, + RIGHT_BRACKET = 362, + LEFT_BRACE = 363, + RIGHT_BRACE = 364, + DOT = 365, + COMMA = 366, + COLON = 367, + EQUAL = 368, + SEMICOLON = 369, + BANG = 370, + DASH = 371, + TILDE = 372, + PLUS = 373, + STAR = 374, + SLASH = 375, + PERCENT = 376, + LEFT_ANGLE = 377, + RIGHT_ANGLE = 378, + VERTICAL_BAR = 379, + CARET = 380, + AMPERSAND = 381, + QUESTION = 382 }; #endif @@ -161,6 +193,7 @@ typedef union YYSTYPE TString *string; float f; int i; + unsigned int u; bool b; }; TSymbol* symbol; @@ -176,6 +209,7 @@ typedef union YYSTYPE union { TPublicType type; TPrecision precision; + TLayoutQualifier layoutQualifier; TQualifier qualifier; TFunction* function; TParameter param; diff --git a/chromium/third_party/angle/src/compiler/intermOut.cpp b/chromium/third_party/angle/src/compiler/translator/intermOut.cpp index 13aa96af6d6..7f94ac31416 100644 --- a/chromium/third_party/angle/src/compiler/intermOut.cpp +++ b/chromium/third_party/angle/src/compiler/translator/intermOut.cpp @@ -1,10 +1,11 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/localintermediate.h" +#include "compiler/translator/localintermediate.h" +#include "compiler/translator/SymbolTable.h" // // Two purposes: @@ -43,10 +44,10 @@ TString TType::getCompleteString() const stream << getQualifierString() << " " << getPrecisionString() << " "; if (array) stream << "array[" << getArraySize() << "] of "; - if (matrix) - stream << size << "X" << size << " matrix of "; - else if (size > 1) - stream << size << "-component vector of "; + if (isMatrix()) + stream << getCols() << "X" << getRows() << " matrix of "; + else if (isVector()) + stream << getNominalSize() << "-component vector of "; stream << getBasicString(); return stream.str(); @@ -103,6 +104,7 @@ bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node) case EOpIndexDirect: out << "direct index"; break; case EOpIndexIndirect: out << "indirect index"; break; case EOpIndexDirectStruct: out << "direct index for structure"; break; + case EOpIndexDirectInterfaceBlock: out << "direct index for interface block"; break; case EOpVectorSwizzle: out << "vector swizzle"; break; case EOpAdd: out << "add"; break; @@ -152,11 +154,16 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node) case EOpPreDecrement: out << "Pre-Decrement"; break; case EOpConvIntToBool: out << "Convert int to bool"; break; + case EOpConvUIntToBool: out << "Convert uint to bool"; break; case EOpConvFloatToBool:out << "Convert float to bool";break; case EOpConvBoolToFloat:out << "Convert bool to float";break; case EOpConvIntToFloat: out << "Convert int to float"; break; + case EOpConvUIntToFloat:out << "Convert uint to float";break; case EOpConvFloatToInt: out << "Convert float to int"; break; case EOpConvBoolToInt: out << "Convert bool to int"; break; + case EOpConvIntToUInt: out << "Convert int to uint"; break; + case EOpConvFloatToUInt:out << "Convert float to uint";break; + case EOpConvBoolToUInt: out << "Convert bool to uint"; break; case EOpRadians: out << "radians"; break; case EOpDegrees: out << "degrees"; break; @@ -232,6 +239,10 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node) case EOpConstructIVec2: out << "Construct ivec2"; break; case EOpConstructIVec3: out << "Construct ivec3"; break; case EOpConstructIVec4: out << "Construct ivec4"; break; + case EOpConstructUInt: out << "Construct uint"; break; + case EOpConstructUVec2: out << "Construct uvec2"; break; + case EOpConstructUVec3: out << "Construct uvec3"; break; + case EOpConstructUVec4: out << "Construct uvec4"; break; case EOpConstructMat2: out << "Construct mat2"; break; case EOpConstructMat3: out << "Construct mat3"; break; case EOpConstructMat4: out << "Construct mat4"; break; @@ -338,6 +349,10 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node) out << node->getUnionArrayPointer()[i].getIConst(); out << " (const int)\n"; break; + case EbtUInt: + out << node->getUnionArrayPointer()[i].getUConst(); + out << " (const uint)\n"; + break; default: out.message(EPrefixInternalError, node->getLine(), "Unknown constant"); break; diff --git a/chromium/third_party/angle/src/compiler/intermediate.h b/chromium/third_party/angle/src/compiler/translator/intermediate.h index 3f2ea14542f..2fdde02e0f6 100644 --- a/chromium/third_party/angle/src/compiler/intermediate.h +++ b/chromium/third_party/angle/src/compiler/translator/intermediate.h @@ -19,9 +19,10 @@ #include "GLSLANG/ShaderLang.h" #include <algorithm> -#include "compiler/Common.h" -#include "compiler/Types.h" -#include "compiler/ConstantUnion.h" +#include <queue> +#include "compiler/translator/Common.h" +#include "compiler/translator/Types.h" +#include "compiler/translator/ConstantUnion.h" // // Operators used by the high-level (parse tree) representation. @@ -50,11 +51,17 @@ enum TOperator { EOpPreDecrement, EOpConvIntToBool, + EOpConvUIntToBool, EOpConvFloatToBool, EOpConvBoolToFloat, EOpConvIntToFloat, + EOpConvUIntToFloat, EOpConvFloatToInt, EOpConvBoolToInt, + EOpConvUIntToInt, + EOpConvIntToUInt, + EOpConvFloatToUInt, + EOpConvBoolToUInt, // // binary operations @@ -86,6 +93,7 @@ enum TOperator { EOpIndexDirect, EOpIndexIndirect, EOpIndexDirectStruct, + EOpIndexDirectInterfaceBlock, EOpVectorSwizzle, @@ -155,6 +163,7 @@ enum TOperator { // EOpConstructInt, + EOpConstructUInt, EOpConstructBool, EOpConstructFloat, EOpConstructVec2, @@ -166,6 +175,9 @@ enum TOperator { EOpConstructIVec2, EOpConstructIVec3, EOpConstructIVec4, + EOpConstructUVec2, + EOpConstructUVec3, + EOpConstructUVec4, EOpConstructMat2, EOpConstructMat3, EOpConstructMat4, @@ -199,6 +211,7 @@ class TIntermTyped; class TIntermSymbol; class TIntermLoop; class TInfoSink; +class TIntermRaw; // // Base class for the tree nodes @@ -226,12 +239,17 @@ public: virtual TIntermSelection* getAsSelectionNode() { return 0; } virtual TIntermSymbol* getAsSymbolNode() { return 0; } virtual TIntermLoop* getAsLoopNode() { return 0; } + virtual TIntermRaw* getAsRawNode() { return 0; } // Replace a child node. Return true if |original| is a child // node and it is replaced; otherwise, return false. virtual bool replaceChildNode( TIntermNode *original, TIntermNode *replacement) = 0; + // For traversing a tree in no particular order, but using + // heap memory. + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const = 0; + protected: TSourceLoc line; }; @@ -261,18 +279,21 @@ public: TBasicType getBasicType() const { return type.getBasicType(); } TQualifier getQualifier() const { return type.getQualifier(); } TPrecision getPrecision() const { return type.getPrecision(); } + int getCols() const { return type.getCols(); } + int getRows() const { return type.getRows(); } int getNominalSize() const { return type.getNominalSize(); } + int getSecondarySize() const { return type.getSecondarySize(); } + bool isInterfaceBlock() const { return type.isInterfaceBlock(); } bool isMatrix() const { return type.isMatrix(); } bool isArray() const { return type.isArray(); } bool isVector() const { return type.isVector(); } bool isScalar() const { return type.isScalar(); } + bool isScalarInt() const { return type.isScalarInt(); } const char* getBasicString() const { return type.getBasicString(); } const char* getQualifierString() const { return type.getQualifierString(); } TString getCompleteString() const { return type.getCompleteString(); } - int totalRegisterCount() const { return type.totalRegisterCount(); } - int elementRegisterCount() const { return type.elementRegisterCount(); } int getArraySize() const { return type.getArraySize(); } protected: @@ -314,6 +335,8 @@ public: void setUnrollFlag(bool flag) { unrollFlag = flag; } bool getUnrollFlag() { return unrollFlag; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const; + protected: TLoopType type; TIntermNode* init; // for-loop initialization @@ -340,6 +363,8 @@ public: TOperator getFlowOp() { return flowOp; } TIntermTyped* getExpression() { return expression; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const; + protected: TOperator flowOp; TIntermTyped* expression; // non-zero except for "return exp;" statements @@ -354,7 +379,7 @@ public: // per process globalpoolallocator, then it causes increased memory usage per compile // it is essential to use "symbol = sym" to assign to symbol TIntermSymbol(int i, const TString& sym, const TType& t) : - TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; } + TIntermTyped(t), id(i) { symbol = sym; } virtual bool hasSideEffects() const { return false; } @@ -362,18 +387,39 @@ public: const TString& getSymbol() const { return symbol; } void setId(int newId) { id = newId; } - void setSymbol(const TString& sym) { symbol = sym; } - - const TString& getOriginalSymbol() const { return originalSymbol; } virtual void traverse(TIntermTraverser*); virtual TIntermSymbol* getAsSymbolNode() { return this; } virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {} + protected: int id; TString symbol; - TString originalSymbol; +}; + +// A Raw node stores raw code, that the translator will insert verbatim +// into the output stream. Useful for transformation operations that make +// complex code that might not fit naturally into the GLSL model. +class TIntermRaw : public TIntermTyped { +public: + TIntermRaw(const TType &t, const TString &rawTextIn) + : TIntermTyped(t), rawText(rawTextIn) + {} + + virtual bool hasSideEffects() const { return false; } + + TString getRawText() const { return rawText; } + + virtual void traverse(TIntermTraverser*); + + virtual TIntermRaw* getAsRawNode() { return this; } + virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {} + +protected: + TString rawText; }; class TIntermConstantUnion : public TIntermTyped { @@ -385,6 +431,7 @@ public: ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; } int getIConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; } + unsigned int getUConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; } float getFConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; } bool getBConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; } @@ -394,6 +441,8 @@ public: TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&); + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {} + protected: ConstantUnion *unionArrayPointer; }; @@ -413,7 +462,7 @@ public: protected: TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {} - TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {} + TIntermOperator(TOperator o, const TType& t) : TIntermTyped(t), op(o) {} TOperator op; }; @@ -440,6 +489,8 @@ public: void setAddIndexClamp() { addIndexClamp = true; } bool getAddIndexClamp() { return addIndexClamp; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const; + protected: TIntermTyped* left; TIntermTyped* right; @@ -453,7 +504,7 @@ protected: // class TIntermUnary : public TIntermOperator { public: - TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {} + TIntermUnary(TOperator o, const TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {} TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {} virtual void traverse(TIntermTraverser*); @@ -470,6 +521,8 @@ public: void setUseEmulatedFunction() { useEmulatedFunction = true; } bool getUseEmulatedFunction() { return useEmulatedFunction; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const; + protected: TIntermTyped* operand; @@ -514,6 +567,8 @@ public: void setUseEmulatedFunction() { useEmulatedFunction = true; } bool getUseEmulatedFunction() { return useEmulatedFunction; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const; + protected: TIntermAggregate(const TIntermAggregate&); // disallow copy constructor TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator @@ -552,6 +607,8 @@ public: TIntermNode* getFalseBlock() const { return falseBlock; } TIntermSelection* getAsSelectionNode() { return this; } + virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const; + protected: TIntermTyped* condition; TIntermNode* trueBlock; @@ -587,6 +644,7 @@ public: virtual ~TIntermTraverser() {} virtual void visitSymbol(TIntermSymbol*) {} + virtual void visitRaw(TIntermRaw*) {} virtual void visitConstantUnion(TIntermConstantUnion*) {} virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;} virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;} @@ -632,4 +690,30 @@ protected: TVector<TIntermNode *> path; }; +// +// For traversing the tree, and computing max depth. +// Takes a maximum depth limit to prevent stack overflow. +// +class TMaxDepthTraverser : public TIntermTraverser +{ +public: + POOL_ALLOCATOR_NEW_DELETE(); + TMaxDepthTraverser(int depthLimit) + : TIntermTraverser(true, true, false, false), + depthLimit(depthLimit) + {} + + virtual bool visitBinary(Visit visit, TIntermBinary*) { return depthCheck(); } + virtual bool visitUnary(Visit visit, TIntermUnary*) { return depthCheck(); } + virtual bool visitSelection(Visit visit, TIntermSelection*) { return depthCheck(); } + virtual bool visitAggregate(Visit visit, TIntermAggregate*) { return depthCheck(); } + virtual bool visitLoop(Visit visit, TIntermLoop*) { return depthCheck(); } + virtual bool visitBranch(Visit visit, TIntermBranch*) { return depthCheck(); } + +protected: + int depthLimit; + + bool depthCheck() const { return maxDepth < depthLimit; } +}; + #endif // __INTERMEDIATE_H diff --git a/chromium/third_party/angle/src/compiler/preprocessor/length_limits.h b/chromium/third_party/angle/src/compiler/translator/length_limits.h index 4f1f71319fc..df70ee5d84a 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/length_limits.h +++ b/chromium/third_party/angle/src/compiler/translator/length_limits.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2011-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,11 +11,11 @@ #if !defined(__LENGTH_LIMITS_H) #define __LENGTH_LIMITS_H 1 +#include "GLSLANG/ShaderLang.h" + // These constants are factored out from the rest of the headers to // make it easier to reference them from the compiler sources. -// These lengths do not include the NULL terminator. -#define MAX_SYMBOL_NAME_LEN 256 -#define MAX_STRING_LEN 511 +size_t GetGlobalMaxTokenSize(ShShaderSpec spec); #endif // !(defined(__LENGTH_LIMITS_H) diff --git a/chromium/third_party/angle/src/compiler/localintermediate.h b/chromium/third_party/angle/src/compiler/translator/localintermediate.h index ccbc40178ac..125dcd989a2 100644 --- a/chromium/third_party/angle/src/compiler/localintermediate.h +++ b/chromium/third_party/angle/src/compiler/translator/localintermediate.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,9 +7,7 @@ #ifndef _LOCAL_INTERMEDIATE_INCLUDED_ #define _LOCAL_INTERMEDIATE_INCLUDED_ -#include "GLSLANG/ShaderLang.h" -#include "compiler/intermediate.h" -#include "compiler/SymbolTable.h" +#include "compiler/translator/intermediate.h" struct TVectorFields { int offsets[4]; @@ -27,10 +25,10 @@ public: TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); - TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&, TSymbolTable&); + TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&); - TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, const TSourceLoc&, TSymbolTable&); + TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, const TSourceLoc&); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&); TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&); @@ -39,13 +37,13 @@ public: TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&); TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ; - bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false); + bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false); TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&); TIntermBranch* addBranch(TOperator, const TSourceLoc&); TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&); TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&); bool postProcess(TIntermNode*); - void remove(TIntermNode*); + void remove(TIntermNode*); void outputTree(TIntermNode*); private: diff --git a/chromium/third_party/angle/src/compiler/osinclude.h b/chromium/third_party/angle/src/compiler/translator/osinclude.h index d8bb1a797c4..c3063d624a8 100644 --- a/chromium/third_party/angle/src/compiler/osinclude.h +++ b/chromium/third_party/angle/src/compiler/translator/osinclude.h @@ -16,6 +16,7 @@ #define ANGLE_OS_WIN #elif defined(__APPLE__) || defined(__linux__) || \ defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__NetBSD__) || defined(__DragonFly__) || \ defined(__sun) || defined(ANDROID) || \ defined(__GLIBC__) || defined(__GNU__) || \ defined(__QNX__) @@ -35,7 +36,7 @@ #endif // ANGLE_OS_WIN -#include "compiler/debug.h" +#include "compiler/translator/compilerdebug.h" // // Thread Local Storage Operations diff --git a/chromium/third_party/angle/src/compiler/ossource_posix.cpp b/chromium/third_party/angle/src/compiler/translator/ossource_posix.cpp index 1e1e699aebc..90a37574441 100644 --- a/chromium/third_party/angle/src/compiler/ossource_posix.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ossource_posix.cpp @@ -7,7 +7,7 @@ // // This file contains the posix specific functions // -#include "compiler/osinclude.h" +#include "compiler/translator/osinclude.h" #if !defined(ANGLE_OS_POSIX) #error Trying to build a posix specific file in a non-posix build. diff --git a/chromium/third_party/angle/src/compiler/ossource_win.cpp b/chromium/third_party/angle/src/compiler/translator/ossource_win.cpp index 89922fef3f4..2cc5871b71d 100644 --- a/chromium/third_party/angle/src/compiler/ossource_win.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ossource_win.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/osinclude.h" +#include "compiler/translator/osinclude.h" // // This file contains contains the window's specific functions // diff --git a/chromium/third_party/angle/src/compiler/parseConst.cpp b/chromium/third_party/angle/src/compiler/translator/parseConst.cpp index 65ed115cbcb..33617e53d9a 100644 --- a/chromium/third_party/angle/src/compiler/parseConst.cpp +++ b/chromium/third_party/angle/src/compiler/translator/parseConst.cpp @@ -1,10 +1,10 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -#include "compiler/ParseContext.h" +#include "compiler/translator/ParseContext.h" // // Use this class to carry along data from node to node in @@ -12,7 +12,7 @@ // class TConstTraverser : public TIntermTraverser { public: - TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) + TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TType& t) : error(false), index(0), unionArray(cUnion), @@ -20,10 +20,10 @@ public: constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), - symbolTable(symTable), size(0), - isMatrix(false), - matrixSize(0) { + isDiagonalMatrixInit(false), + matrixCols(0), + matrixRows(0) { } bool error; @@ -44,10 +44,10 @@ protected: TOperator constructorType; bool singleConstantParam; TInfoSink& infoSink; - TSymbolTable& symbolTable; size_t size; // size of the constructor ( 4 for vec4) - bool isMatrix; - size_t matrixSize; // dimension of the matrix (nominal size and not the instance size) + bool isDiagonalMatrixInit; + int matrixCols; // columns of the matrix + int matrixRows; // rows of the matrix }; // @@ -118,8 +118,9 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node) size = node->getType().getObjectSize(); if (node->getType().isMatrix()) { - isMatrix = true; - matrixSize = node->getType().getNominalSize(); + isDiagonalMatrixInit = true; + matrixCols = node->getType().getCols(); + matrixRows = node->getType().getRows(); } } @@ -136,8 +137,9 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node) singleConstantParam = false; constructorType = EOpNull; size = 0; - isMatrix = false; - matrixSize = 0; + isDiagonalMatrixInit = false; + matrixCols = 0; + matrixRows = 0; } return false; } @@ -165,10 +167,10 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) return; if (!singleConstantParam) { - size_t size = node->getType().getObjectSize(); + size_t objectSize = node->getType().getObjectSize(); ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); - for (size_t i = 0; i < size; i++) { + for (size_t i=0; i < objectSize; i++) { if (index >= instanceSize) return; leftUnionArray[index] = rightUnionArray[i]; @@ -178,8 +180,8 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) } else { size_t totalSize = index + size; ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); - if (!isMatrix) { - size_t count = 0; + if (!isDiagonalMatrixInit) { + int count = 0; for (size_t i = index; i < totalSize; i++) { if (i >= instanceSize) return; @@ -191,21 +193,25 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) if (node->getType().getObjectSize() > 1) count++; } - } else { // for matrix constructors - size_t count = 0; - size_t element = index; - for (size_t i = index; i < totalSize; i++) { - if (i >= instanceSize) - return; - if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 ) - leftUnionArray[i] = rightUnionArray[count]; - else - leftUnionArray[i].setFConst(0.0f); - - (index)++; - - if (node->getType().getObjectSize() > 1) - count++; + } + else + { + // for matrix diagonal constructors from a single scalar + for (int i = 0, col = 0; col < matrixCols; col++) + { + for (int row = 0; row < matrixRows; row++, i++) + { + if (col == row) + { + leftUnionArray[i] = rightUnionArray[0]; + } + else + { + leftUnionArray[i].setFConst(0.0f); + } + + (index)++; + } } } } @@ -230,12 +236,12 @@ bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node) // Individual functions can be initialized to 0 to skip processing of that // type of node. It's children will still be processed. // -bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam) +bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TType t, bool singleConstantParam) { if (root == 0) return false; - TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t); + TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, t); root->traverse(&it); if (it.error) diff --git a/chromium/third_party/angle/src/compiler/timing/RestrictFragmentShaderTiming.cpp b/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp index b9d2bab17f8..48d44c72d17 100644 --- a/chromium/third_party/angle/src/compiler/timing/RestrictFragmentShaderTiming.cpp +++ b/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp @@ -4,10 +4,10 @@ // found in the LICENSE file. // -#include "compiler/InfoSink.h" -#include "compiler/ParseContext.h" -#include "compiler/depgraph/DependencyGraphOutput.h" -#include "compiler/timing/RestrictFragmentShaderTiming.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/ParseContext.h" +#include "compiler/translator/depgraph/DependencyGraphOutput.h" +#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink) : mSink(sink) @@ -31,6 +31,15 @@ RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink) mSamplingOps.insert("texture2DRect(1;vf2;"); mSamplingOps.insert("texture2DRectProj(1;vf3;"); mSamplingOps.insert("texture2DRectProj(1;vf4;"); + // Sampling ops provided by EXT_shader_texture_lod. + mSamplingOps.insert("texture2DLodEXT(1;vf2;f1;"); + mSamplingOps.insert("texture2DProjLodEXT(1;vf3;f1;"); + mSamplingOps.insert("texture2DProjLodEXT(1;vf4;f1;"); + mSamplingOps.insert("textureCubeLodEXT(1;vf4;f1;"); + mSamplingOps.insert("texture2DGradEXT(1;vf2;vf2;vf2;"); + mSamplingOps.insert("texture2DProjGradEXT(1;vf3;vf2;vf2;"); + mSamplingOps.insert("texture2DProjGradEXT(1;vf4;vf2;vf2;"); + mSamplingOps.insert("textureCubeGradEXT(1;vf3;vf3;vf3;"); } // FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc. diff --git a/chromium/third_party/angle/src/compiler/timing/RestrictFragmentShaderTiming.h b/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h index 899165ca287..e77d8c21cbc 100644 --- a/chromium/third_party/angle/src/compiler/timing/RestrictFragmentShaderTiming.h +++ b/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h @@ -7,10 +7,8 @@ #ifndef COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_ #define COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_ -#include "GLSLANG/ShaderLang.h" - -#include "compiler/intermediate.h" -#include "compiler/depgraph/DependencyGraph.h" +#include "compiler/translator/intermediate.h" +#include "compiler/translator/depgraph/DependencyGraph.h" class TInfoSinkBase; diff --git a/chromium/third_party/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp b/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp index 355eb62d650..7c1208a2986 100644 --- a/chromium/third_party/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp +++ b/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/timing/RestrictVertexShaderTiming.h" +#include "compiler/translator/timing/RestrictVertexShaderTiming.h" void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node) { @@ -12,6 +12,6 @@ void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node) ++mNumErrors; mSink.message(EPrefixError, node->getLine(), - "Samplers are not permitted in vertex shaders"); + "Samplers are not permitted in vertex shaders.\n"); } } diff --git a/chromium/third_party/angle/src/compiler/timing/RestrictVertexShaderTiming.h b/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h index 19a05fa68bc..d461fbdbfea 100644 --- a/chromium/third_party/angle/src/compiler/timing/RestrictVertexShaderTiming.h +++ b/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h @@ -7,10 +7,8 @@ #ifndef COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_ #define COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_ -#include "GLSLANG/ShaderLang.h" - -#include "compiler/intermediate.h" -#include "compiler/InfoSink.h" +#include "compiler/translator/intermediate.h" +#include "compiler/translator/InfoSink.h" class TInfoSinkBase; diff --git a/chromium/third_party/angle/src/compiler/util.cpp b/chromium/third_party/angle/src/compiler/translator/util.cpp index d6e5eeed91f..077bdcc48b8 100644 --- a/chromium/third_party/angle/src/compiler/util.cpp +++ b/chromium/third_party/angle/src/compiler/translator/util.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "compiler/util.h" +#include "compiler/translator/util.h" #include <limits> diff --git a/chromium/third_party/angle/src/compiler/util.h b/chromium/third_party/angle/src/compiler/translator/util.h index dc69f39060d..dc69f39060d 100644 --- a/chromium/third_party/angle/src/compiler/util.h +++ b/chromium/third_party/angle/src/compiler/translator/util.h |