summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler')
-rw-r--r--src/3rdparty/angle/src/compiler/BaseTypes.h8
-rw-r--r--src/3rdparty/angle/src/compiler/Common.h42
-rw-r--r--src/3rdparty/angle/src/compiler/Compiler.cpp212
-rw-r--r--src/3rdparty/angle/src/compiler/ConstantUnion.h2
-rw-r--r--src/3rdparty/angle/src/compiler/DetectCallDepth.cpp185
-rw-r--r--src/3rdparty/angle/src/compiler/DetectCallDepth.h80
-rw-r--r--src/3rdparty/angle/src/compiler/Diagnostics.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/InfoSink.cpp25
-rw-r--r--src/3rdparty/angle/src/compiler/InfoSink.h8
-rw-r--r--src/3rdparty/angle/src/compiler/Initialize.cpp799
-rw-r--r--src/3rdparty/angle/src/compiler/Initialize.h16
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeDll.cpp89
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeDll.h5
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeGLPosition.cpp61
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeGLPosition.h33
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeGlobals.h2
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeParseContext.cpp78
-rw-r--r--src/3rdparty/angle/src/compiler/InitializeParseContext.h15
-rw-r--r--src/3rdparty/angle/src/compiler/Intermediate.cpp147
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSL.cpp14
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSL.h1
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp81
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSLBase.h3
-rw-r--r--src/3rdparty/angle/src/compiler/OutputHLSL.cpp324
-rw-r--r--src/3rdparty/angle/src/compiler/OutputHLSL.h13
-rw-r--r--src/3rdparty/angle/src/compiler/ParseHelper.cpp355
-rw-r--r--src/3rdparty/angle/src/compiler/ParseHelper.h89
-rw-r--r--src/3rdparty/angle/src/compiler/PoolAlloc.cpp68
-rw-r--r--src/3rdparty/angle/src/compiler/PoolAlloc.h10
-rw-r--r--src/3rdparty/angle/src/compiler/ShHandle.h14
-rw-r--r--src/3rdparty/angle/src/compiler/ShaderLang.cpp171
-rw-r--r--src/3rdparty/angle/src/compiler/SymbolTable.cpp201
-rw-r--r--src/3rdparty/angle/src/compiler/SymbolTable.h151
-rw-r--r--src/3rdparty/angle/src/compiler/Types.h240
-rw-r--r--src/3rdparty/angle/src/compiler/ValidateLimitations.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/VariableInfo.cpp204
-rw-r--r--src/3rdparty/angle/src/compiler/VariableInfo.h24
-rw-r--r--src/3rdparty/angle/src/compiler/glslang.l310
-rw-r--r--src/3rdparty/angle/src/compiler/glslang.y935
-rw-r--r--src/3rdparty/angle/src/compiler/intermOut.cpp17
-rw-r--r--src/3rdparty/angle/src/compiler/intermediate.h33
-rw-r--r--src/3rdparty/angle/src/compiler/localintermediate.h45
-rw-r--r--src/3rdparty/angle/src/compiler/parseConst.cpp42
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp33
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h6
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h3
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l12
-rw-r--r--src/3rdparty/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp6
-rw-r--r--src/3rdparty/angle/src/compiler/util.cpp39
-rw-r--r--src/3rdparty/angle/src/compiler/util.h17
50 files changed, 2569 insertions, 2703 deletions
diff --git a/src/3rdparty/angle/src/compiler/BaseTypes.h b/src/3rdparty/angle/src/compiler/BaseTypes.h
index af4c7e3ed9..1631f4f779 100644
--- a/src/3rdparty/angle/src/compiler/BaseTypes.h
+++ b/src/3rdparty/angle/src/compiler/BaseTypes.h
@@ -90,10 +90,6 @@ enum TQualifier
EvqInvariantVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment
- // pack/unpack input and output
- EvqInput,
- EvqOutput,
-
// parameters
EvqIn,
EvqOut,
@@ -112,6 +108,7 @@ enum TQualifier
// built-ins written by fragment shader
EvqFragColor,
EvqFragData,
+ EvqFragDepth,
// end of list
EvqLast
@@ -137,14 +134,13 @@ inline const char* getQualifierString(TQualifier q)
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break;
- case EvqInput: return "input"; break;
- case EvqOutput: return "output"; 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";
}
}
diff --git a/src/3rdparty/angle/src/compiler/Common.h b/src/3rdparty/angle/src/compiler/Common.h
index 27a5598290..46f9440fff 100644
--- a/src/3rdparty/angle/src/compiler/Common.h
+++ b/src/3rdparty/angle/src/compiler/Common.h
@@ -14,36 +14,24 @@
#include "compiler/PoolAlloc.h"
-// We need two pieces of information to report errors/warnings - string and
-// line number. We encode these into a single int so that it can be easily
-// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store
-// line number while the rest store the string number. Since the shaders are
-// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE
-// can be increased to alleviate this issue.
-typedef int TSourceLoc;
-const unsigned int SOURCE_LOC_LINE_SIZE = 16; // in bits.
-const unsigned int SOURCE_LOC_LINE_MASK = (1 << SOURCE_LOC_LINE_SIZE) - 1;
-
-inline TSourceLoc EncodeSourceLoc(int string, int line) {
- return (string << SOURCE_LOC_LINE_SIZE) | (line & SOURCE_LOC_LINE_MASK);
-}
-
-inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
- if (string) *string = loc >> SOURCE_LOC_LINE_SIZE;
- if (line) *line = loc & SOURCE_LOC_LINE_MASK;
-}
+struct TSourceLoc {
+ int first_file;
+ int first_line;
+ int last_file;
+ int last_line;
+};
//
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
//
-#define POOL_ALLOCATOR_NEW_DELETE(A) \
- void* operator new(size_t s) { return (A).allocate(s); } \
- void* operator new(size_t, void *_Where) { return (_Where); } \
- void operator delete(void*) { } \
- void operator delete(void *, void *) { } \
- void* operator new[](size_t s) { return (A).allocate(s); } \
- void* operator new[](size_t, void *_Where) { return (_Where); } \
- void operator delete[](void*) { } \
+#define POOL_ALLOCATOR_NEW_DELETE() \
+ void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+ void* operator new(size_t, void *_Where) { return (_Where); } \
+ void operator delete(void*) { } \
+ void operator delete(void *, void *) { } \
+ void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+ void* operator new[](size_t, void *_Where) { return (_Where); } \
+ void operator delete[](void*) { } \
void operator delete[](void *, void *) { }
//
@@ -54,7 +42,7 @@ typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TStri
typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
inline TString* NewPoolTString(const char* s)
{
- void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
+ void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
return new(memory) TString(s);
}
diff --git a/src/3rdparty/angle/src/compiler/Compiler.cpp b/src/3rdparty/angle/src/compiler/Compiler.cpp
index c8c79e7147..ee64057ac4 100644
--- a/src/3rdparty/angle/src/compiler/Compiler.cpp
+++ b/src/3rdparty/angle/src/compiler/Compiler.cpp
@@ -1,13 +1,14 @@
//
-// 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.
//
#include "compiler/BuiltInFunctionEmulator.h"
-#include "compiler/DetectRecursion.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/ParseHelper.h"
@@ -27,66 +28,34 @@ bool isWebGLBasedSpec(ShShaderSpec spec)
}
namespace {
-bool InitializeSymbolTable(
- const TBuiltInStrings& builtInStrings,
- ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
- TInfoSink& infoSink, TSymbolTable& symbolTable)
-{
- TIntermediate intermediate(infoSink);
- TExtensionBehavior extBehavior;
- InitExtensionBehavior(resources, extBehavior);
- // The builtins deliberately don't specify precisions for the function
- // arguments and return types. For that reason we don't try to check them.
- TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
- parseContext.fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
-
- GlobalParseContext = &parseContext;
-
- assert(symbolTable.isEmpty());
- //
- // Parse the built-ins. This should only happen once per
- // language symbol table.
- //
- // Push the symbol table to give it an initial scope. This
- // push should not have a corresponding pop, so that built-ins
- // are preserved, and the test for an empty table fails.
- //
- symbolTable.push();
-
- for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
- {
- const char* builtInShaders = i->c_str();
- int builtInLengths = static_cast<int>(i->size());
- if (builtInLengths <= 0)
- continue;
-
- if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
- {
- infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
- return false;
- }
- }
-
- IdentifyBuiltIns(type, spec, resources, symbolTable);
-
- return true;
-}
-
class TScopedPoolAllocator {
public:
- TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
- : mAllocator(allocator), mPushPopAllocator(pushPop) {
- if (mPushPopAllocator) mAllocator->push();
+ TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) {
+ mAllocator->push();
SetGlobalPoolAllocator(mAllocator);
}
~TScopedPoolAllocator() {
SetGlobalPoolAllocator(NULL);
- if (mPushPopAllocator) mAllocator->pop();
+ mAllocator->pop();
}
private:
TPoolAllocator* mAllocator;
- bool mPushPopAllocator;
+};
+
+class TScopedSymbolTableLevel {
+public:
+ TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) {
+ ASSERT(mTable->atBuiltInLevel());
+ mTable->push();
+ }
+ ~TScopedSymbolTableLevel() {
+ while (!mTable->atBuiltInLevel())
+ mTable->pop();
+ }
+
+private:
+ TSymbolTable* mTable;
};
} // namespace
@@ -103,6 +72,9 @@ TShHandleBase::~TShHandleBase() {
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
shaderSpec(spec),
+ maxUniformVectors(0),
+ maxExpressionComplexity(0),
+ maxCallStackDepth(0),
fragmentPrecisionHigh(false),
clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
builtInFunctionEmulator(type)
@@ -121,7 +93,10 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
resources.MaxVertexUniformVectors :
resources.MaxFragmentUniformVectors;
- TScopedPoolAllocator scopedAlloc(&allocator, false);
+ maxExpressionComplexity = resources.MaxExpressionComplexity;
+ maxCallStackDepth = resources.MaxCallStackDepth;
+
+ SetGlobalPoolAllocator(&allocator);
// Generate built-in symbol table.
if (!InitBuiltInSymbolTable(resources))
@@ -141,7 +116,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
size_t numStrings,
int compileOptions)
{
- TScopedPoolAllocator scopedAlloc(&allocator, true);
+ TScopedPoolAllocator scopedAlloc(&allocator);
clearResults();
if (numStrings == 0)
@@ -165,13 +140,11 @@ bool TCompiler::compile(const char* const shaderStrings[],
shaderType, shaderSpec, compileOptions, true,
sourcePath, infoSink);
parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
- GlobalParseContext = &parseContext;
+ SetGlobalParseContext(&parseContext);
// We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level.
- symbolTable.push();
- if (!symbolTable.atGlobalLevel())
- infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
+ TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
// Parse shader.
bool success =
@@ -182,7 +155,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
success = intermediate.postProcess(root);
if (success)
- success = detectRecursion(root);
+ success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
success = validateLimitations(root);
@@ -205,6 +178,10 @@ 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.
@@ -212,12 +189,18 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
mapLongVariableNames(root);
- if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
- collectAttribsUniforms(root);
+ if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) {
+ InitializeGLPosition initGLPosition;
+ root->traverse(&initGLPosition);
+ }
+
+ if (success && (compileOptions & SH_VARIABLES)) {
+ collectVariables(root);
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
success = enforcePackingRestrictions();
if (!success) {
- infoSink.info.message(EPrefixError, "too many uniforms");
+ infoSink.info.prefix(EPrefixError);
+ infoSink.info << "too many uniforms";
}
}
}
@@ -231,22 +214,58 @@ bool TCompiler::compile(const char* const shaderStrings[],
// Cleanup memory.
intermediate.remove(parseContext.treeRoot);
- // Ensure symbol table is returned to the built-in level,
- // throwing away all but the built-ins.
- while (!symbolTable.atBuiltInLevel())
- symbolTable.pop();
return success;
}
-bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
+bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
{
- TBuiltIns builtIns;
-
compileResources = resources;
- builtIns.initialize(shaderType, shaderSpec, resources);
- return InitializeSymbolTable(builtIns.getBuiltInStrings(),
- shaderType, shaderSpec, resources, infoSink, symbolTable);
+
+ assert(symbolTable.isEmpty());
+ symbolTable.push();
+
+ TPublicType integer;
+ integer.type = EbtInt;
+ integer.size = 1;
+ integer.matrix = false;
+ integer.array = false;
+
+ TPublicType floatingPoint;
+ floatingPoint.type = EbtFloat;
+ floatingPoint.size = 1;
+ floatingPoint.matrix = false;
+ floatingPoint.array = false;
+
+ TPublicType sampler;
+ sampler.size = 1;
+ sampler.matrix = false;
+ sampler.array = false;
+
+ switch(shaderType)
+ {
+ case SH_FRAGMENT_SHADER:
+ symbolTable.setDefaultPrecision(integer, EbpMedium);
+ break;
+ case SH_VERTEX_SHADER:
+ symbolTable.setDefaultPrecision(integer, EbpHigh);
+ symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
+ break;
+ 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) {
+ sampler.type = static_cast<TBasicType>(samplerType);
+ symbolTable.setDefaultPrecision(sampler, EbpLow);
+ }
+
+ InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
+
+ IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
+
+ return true;
}
void TCompiler::clearResults()
@@ -258,24 +277,31 @@ void TCompiler::clearResults()
attribs.clear();
uniforms.clear();
+ varyings.clear();
builtInFunctionEmulator.Cleanup();
nameMap.clear();
}
-bool TCompiler::detectRecursion(TIntermNode* root)
+bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
{
- DetectRecursion detect;
+ DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
root->traverse(&detect);
- switch (detect.detectRecursion()) {
- case DetectRecursion::kErrorNone:
+ switch (detect.detectCallDepth()) {
+ case DetectCallDepth::kErrorNone:
return true;
- case DetectRecursion::kErrorMissingMain:
- infoSink.info.message(EPrefixError, "Missing main()");
+ 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 DetectRecursion::kErrorRecursion:
- infoSink.info.message(EPrefixError, "Function recursion detected");
+ case DetectCallDepth::kErrorMaxDepthExceeded:
+ infoSink.info.prefix(EPrefixError);
+ infoSink.info << "Function call stack too deep";
return false;
default:
UNREACHABLE();
@@ -321,6 +347,28 @@ bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
}
}
+bool TCompiler::limitExpressionComplexity(TIntermNode* root)
+{
+ TIntermTraverser traverser;
+ root->traverse(&traverser);
+ TDependencyGraph graph(root);
+
+ for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
+ iter != graph.endUserDefinedFunctionCalls();
+ ++iter)
+ {
+ TGraphFunctionCall* samplerSymbol = *iter;
+ TDependencyGraphTraverser graphTraverser;
+ samplerSymbol->traverse(&graphTraverser);
+ }
+
+ if (traverser.getMaxDepth() > maxExpressionComplexity) {
+ infoSink.info << "Expression too complex.";
+ return false;
+ }
+ return true;
+}
+
bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
{
RestrictFragmentShaderTiming restrictor(infoSink.info);
@@ -335,9 +383,9 @@ bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
return restrictor.numErrors() == 0;
}
-void TCompiler::collectAttribsUniforms(TIntermNode* root)
+void TCompiler::collectVariables(TIntermNode* root)
{
- CollectAttribsUniforms collect(attribs, uniforms, hashFunction);
+ CollectVariables collect(attribs, uniforms, varyings, hashFunction);
root->traverse(&collect);
}
diff --git a/src/3rdparty/angle/src/compiler/ConstantUnion.h b/src/3rdparty/angle/src/compiler/ConstantUnion.h
index 32af4d38b0..b1e37885f9 100644
--- a/src/3rdparty/angle/src/compiler/ConstantUnion.h
+++ b/src/3rdparty/angle/src/compiler/ConstantUnion.h
@@ -11,13 +11,13 @@
class ConstantUnion {
public:
+ POOL_ALLOCATOR_NEW_DELETE();
ConstantUnion()
{
iConst = 0;
type = EbtVoid;
}
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
void setIConst(int i) {iConst = i; type = EbtInt; }
void setFConst(float f) {fConst = f; type = EbtFloat; }
void setBConst(bool b) {bConst = b; type = EbtBool; }
diff --git a/src/3rdparty/angle/src/compiler/DetectCallDepth.cpp b/src/3rdparty/angle/src/compiler/DetectCallDepth.cpp
new file mode 100644
index 0000000000..60df52c715
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/DetectCallDepth.cpp
@@ -0,0 +1,185 @@
+//
+// 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/DetectCallDepth.h"
+#include "compiler/InfoSink.h"
+
+DetectCallDepth::FunctionNode::FunctionNode(const TString& fname)
+ : name(fname),
+ visit(PreVisit)
+{
+}
+
+const TString& DetectCallDepth::FunctionNode::getName() const
+{
+ return name;
+}
+
+void DetectCallDepth::FunctionNode::addCallee(
+ DetectCallDepth::FunctionNode* callee)
+{
+ for (size_t i = 0; i < callees.size(); ++i) {
+ if (callees[i] == callee)
+ return;
+ }
+ callees.push_back(callee);
+}
+
+int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDepth, int depth)
+{
+ ASSERT(visit == PreVisit);
+ ASSERT(detectCallDepth);
+
+ int maxDepth = depth;
+ visit = InVisit;
+ for (size_t i = 0; i < callees.size(); ++i) {
+ switch (callees[i]->visit) {
+ case InVisit:
+ // cycle detected, i.e., recursion detected.
+ return kInfiniteCallDepth;
+ case PostVisit:
+ break;
+ case PreVisit: {
+ // Check before we recurse so we don't go too depth
+ if (detectCallDepth->checkExceedsMaxDepth(depth))
+ return depth;
+ int callDepth = callees[i]->detectCallDepth(detectCallDepth, depth + 1);
+ // Check after we recurse so we can exit immediately and provide info.
+ if (detectCallDepth->checkExceedsMaxDepth(callDepth)) {
+ detectCallDepth->getInfoSink().info << "<-" << callees[i]->getName();
+ return callDepth;
+ }
+ maxDepth = std::max(callDepth, maxDepth);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ visit = PostVisit;
+ return maxDepth;
+}
+
+void DetectCallDepth::FunctionNode::reset()
+{
+ visit = PreVisit;
+}
+
+DetectCallDepth::DetectCallDepth(TInfoSink& infoSink, bool limitCallStackDepth, int maxCallStackDepth)
+ : TIntermTraverser(true, false, true, false),
+ currentFunction(NULL),
+ infoSink(infoSink),
+ maxDepth(limitCallStackDepth ? maxCallStackDepth : FunctionNode::kInfiniteCallDepth)
+{
+}
+
+DetectCallDepth::~DetectCallDepth()
+{
+ for (size_t i = 0; i < functions.size(); ++i)
+ delete functions[i];
+}
+
+bool DetectCallDepth::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+ switch (node->getOp())
+ {
+ case EOpPrototype:
+ // Function declaration.
+ // Don't add FunctionNode here because node->getName() is the
+ // unmangled function name.
+ break;
+ case EOpFunction: {
+ // Function definition.
+ if (visit == PreVisit) {
+ currentFunction = findFunctionByName(node->getName());
+ if (currentFunction == NULL) {
+ currentFunction = new FunctionNode(node->getName());
+ functions.push_back(currentFunction);
+ }
+ } else if (visit == PostVisit) {
+ currentFunction = NULL;
+ }
+ break;
+ }
+ case EOpFunctionCall: {
+ // Function call.
+ if (visit == PreVisit) {
+ FunctionNode* func = findFunctionByName(node->getName());
+ if (func == NULL) {
+ func = new FunctionNode(node->getName());
+ functions.push_back(func);
+ }
+ if (currentFunction)
+ currentFunction->addCallee(func);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+}
+
+bool DetectCallDepth::checkExceedsMaxDepth(int depth)
+{
+ return depth >= maxDepth;
+}
+
+void DetectCallDepth::resetFunctionNodes()
+{
+ for (size_t i = 0; i < functions.size(); ++i) {
+ functions[i]->reset();
+ }
+}
+
+DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepthForFunction(FunctionNode* func)
+{
+ currentFunction = NULL;
+ resetFunctionNodes();
+
+ int maxCallDepth = func->detectCallDepth(this, 1);
+
+ if (maxCallDepth == FunctionNode::kInfiniteCallDepth)
+ return kErrorRecursion;
+
+ if (maxCallDepth >= maxDepth)
+ return kErrorMaxDepthExceeded;
+
+ return kErrorNone;
+}
+
+DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepth()
+{
+ if (maxDepth != FunctionNode::kInfiniteCallDepth) {
+ // Check all functions because the driver may fail on them
+ // TODO: Before detectingRecursion, strip unused functions.
+ for (size_t i = 0; i < functions.size(); ++i) {
+ ErrorCode error = detectCallDepthForFunction(functions[i]);
+ if (error != kErrorNone)
+ return error;
+ }
+ } else {
+ FunctionNode* main = findFunctionByName("main(");
+ if (main == NULL)
+ return kErrorMissingMain;
+
+ return detectCallDepthForFunction(main);
+ }
+
+ return kErrorNone;
+}
+
+DetectCallDepth::FunctionNode* DetectCallDepth::findFunctionByName(
+ const TString& name)
+{
+ for (size_t i = 0; i < functions.size(); ++i) {
+ if (functions[i]->getName() == name)
+ return functions[i];
+ }
+ return NULL;
+}
+
diff --git a/src/3rdparty/angle/src/compiler/DetectCallDepth.h b/src/3rdparty/angle/src/compiler/DetectCallDepth.h
new file mode 100644
index 0000000000..89e85f88f6
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/DetectCallDepth.h
@@ -0,0 +1,80 @@
+//
+// 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 COMPILER_DETECT_RECURSION_H_
+#define COMPILER_DETECT_RECURSION_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <limits.h>
+#include "compiler/intermediate.h"
+#include "compiler/VariableInfo.h"
+
+class TInfoSink;
+
+// Traverses intermediate tree to detect function recursion.
+class DetectCallDepth : public TIntermTraverser {
+public:
+ enum ErrorCode {
+ kErrorMissingMain,
+ kErrorRecursion,
+ kErrorMaxDepthExceeded,
+ kErrorNone
+ };
+
+ DetectCallDepth(TInfoSink& infoSync, bool limitCallStackDepth, int maxCallStackDepth);
+ ~DetectCallDepth();
+
+ virtual bool visitAggregate(Visit, TIntermAggregate*);
+
+ bool checkExceedsMaxDepth(int depth);
+
+ ErrorCode detectCallDepth();
+
+private:
+ class FunctionNode {
+ public:
+ static const int kInfiniteCallDepth = INT_MAX;
+
+ FunctionNode(const TString& fname);
+
+ const TString& getName() const;
+
+ // If a function is already in the callee list, this becomes a no-op.
+ void addCallee(FunctionNode* callee);
+
+ // Returns kInifinityCallDepth if recursive function calls are detected.
+ int detectCallDepth(DetectCallDepth* detectCallDepth, int depth);
+
+ // Reset state.
+ void reset();
+
+ private:
+ // mangled function name is unique.
+ TString name;
+
+ // functions that are directly called by this function.
+ TVector<FunctionNode*> callees;
+
+ Visit visit;
+ };
+
+ ErrorCode detectCallDepthForFunction(FunctionNode* func);
+ FunctionNode* findFunctionByName(const TString& name);
+ void resetFunctionNodes();
+
+ TInfoSink& getInfoSink() { return infoSink; }
+
+ TVector<FunctionNode*> functions;
+ FunctionNode* currentFunction;
+ TInfoSink& infoSink;
+ int maxDepth;
+
+ DetectCallDepth(const DetectCallDepth&);
+ void operator=(const DetectCallDepth&);
+};
+
+#endif // COMPILER_DETECT_RECURSION_H_
diff --git a/src/3rdparty/angle/src/compiler/Diagnostics.cpp b/src/3rdparty/angle/src/compiler/Diagnostics.cpp
index 06f370dbe5..8a38c41a65 100644
--- a/src/3rdparty/angle/src/compiler/Diagnostics.cpp
+++ b/src/3rdparty/angle/src/compiler/Diagnostics.cpp
@@ -46,7 +46,7 @@ void TDiagnostics::writeInfo(Severity severity,
TInfoSinkBase& sink = mInfoSink.info;
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */
sink.prefix(prefix);
- sink.location(EncodeSourceLoc(loc.file, loc.line));
+ sink.location(loc.file, loc.line);
sink << "'" << token << "' : " << reason << " " << extra << "\n";
}
diff --git a/src/3rdparty/angle/src/compiler/InfoSink.cpp b/src/3rdparty/angle/src/compiler/InfoSink.cpp
index ba32f781f5..d20a6c0175 100644
--- a/src/3rdparty/angle/src/compiler/InfoSink.cpp
+++ b/src/3rdparty/angle/src/compiler/InfoSink.cpp
@@ -6,8 +6,8 @@
#include "compiler/InfoSink.h"
-void TInfoSinkBase::prefix(TPrefixType message) {
- switch(message) {
+void TInfoSinkBase::prefix(TPrefixType p) {
+ switch(p) {
case EPrefixNone:
break;
case EPrefixWarning:
@@ -31,29 +31,24 @@ void TInfoSinkBase::prefix(TPrefixType message) {
}
}
-void TInfoSinkBase::location(TSourceLoc loc) {
- int string = 0, line = 0;
- DecodeSourceLoc(loc, &string, &line);
-
+void TInfoSinkBase::location(int file, int line) {
TPersistStringStream stream;
if (line)
- stream << string << ":" << line;
+ stream << file << ":" << line;
else
- stream << string << ":? ";
+ stream << file << ":? ";
stream << ": ";
sink.append(stream.str());
}
-void TInfoSinkBase::message(TPrefixType message, const char* s) {
- prefix(message);
- sink.append(s);
- sink.append("\n");
+void TInfoSinkBase::location(const TSourceLoc& loc) {
+ location(loc.first_file, loc.first_line);
}
-void TInfoSinkBase::message(TPrefixType message, const char* s, TSourceLoc loc) {
- prefix(message);
+void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m) {
+ prefix(p);
location(loc);
- sink.append(s);
+ sink.append(m);
sink.append("\n");
}
diff --git a/src/3rdparty/angle/src/compiler/InfoSink.h b/src/3rdparty/angle/src/compiler/InfoSink.h
index e2224e918d..6888838142 100644
--- a/src/3rdparty/angle/src/compiler/InfoSink.h
+++ b/src/3rdparty/angle/src/compiler/InfoSink.h
@@ -96,10 +96,10 @@ public:
const TPersistString& str() const { return sink; }
const char* c_str() const { return sink.c_str(); }
- void prefix(TPrefixType message);
- void location(TSourceLoc loc);
- void message(TPrefixType message, const char* s);
- void message(TPrefixType message, const char* s, TSourceLoc loc);
+ void prefix(TPrefixType p);
+ void location(int file, int line);
+ void location(const TSourceLoc& loc);
+ void message(TPrefixType p, const TSourceLoc& loc, const char* m);
private:
TPersistString sink;
diff --git a/src/3rdparty/angle/src/compiler/Initialize.cpp b/src/3rdparty/angle/src/compiler/Initialize.cpp
index 97b46f898e..236383d874 100644
--- a/src/3rdparty/angle/src/compiler/Initialize.cpp
+++ b/src/3rdparty/angle/src/compiler/Initialize.cpp
@@ -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.
//
@@ -14,513 +14,413 @@
#include "compiler/intermediate.h"
-//============================================================================
-//
-// Prototypes for built-in functions seen by both vertex and fragment shaders.
-//
-//============================================================================
-static TString BuiltInFunctionsCommon(const ShBuiltInResources& resources)
+void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
{
- TString s;
+ 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.
//
- s.append(TString("float radians(float degrees);"));
- s.append(TString("vec2 radians(vec2 degrees);"));
- s.append(TString("vec3 radians(vec3 degrees);"));
- s.append(TString("vec4 radians(vec4 degrees);"));
-
- s.append(TString("float degrees(float radians);"));
- s.append(TString("vec2 degrees(vec2 radians);"));
- s.append(TString("vec3 degrees(vec3 radians);"));
- s.append(TString("vec4 degrees(vec4 radians);"));
-
- s.append(TString("float sin(float angle);"));
- s.append(TString("vec2 sin(vec2 angle);"));
- s.append(TString("vec3 sin(vec3 angle);"));
- s.append(TString("vec4 sin(vec4 angle);"));
-
- s.append(TString("float cos(float angle);"));
- s.append(TString("vec2 cos(vec2 angle);"));
- s.append(TString("vec3 cos(vec3 angle);"));
- s.append(TString("vec4 cos(vec4 angle);"));
-
- s.append(TString("float tan(float angle);"));
- s.append(TString("vec2 tan(vec2 angle);"));
- s.append(TString("vec3 tan(vec3 angle);"));
- s.append(TString("vec4 tan(vec4 angle);"));
-
- s.append(TString("float asin(float x);"));
- s.append(TString("vec2 asin(vec2 x);"));
- s.append(TString("vec3 asin(vec3 x);"));
- s.append(TString("vec4 asin(vec4 x);"));
-
- s.append(TString("float acos(float x);"));
- s.append(TString("vec2 acos(vec2 x);"));
- s.append(TString("vec3 acos(vec3 x);"));
- s.append(TString("vec4 acos(vec4 x);"));
-
- s.append(TString("float atan(float y, float x);"));
- s.append(TString("vec2 atan(vec2 y, vec2 x);"));
- s.append(TString("vec3 atan(vec3 y, vec3 x);"));
- s.append(TString("vec4 atan(vec4 y, vec4 x);"));
-
- s.append(TString("float atan(float y_over_x);"));
- s.append(TString("vec2 atan(vec2 y_over_x);"));
- s.append(TString("vec3 atan(vec3 y_over_x);"));
- s.append(TString("vec4 atan(vec4 y_over_x);"));
+ 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.
//
- s.append(TString("float pow(float x, float y);"));
- s.append(TString("vec2 pow(vec2 x, vec2 y);"));
- s.append(TString("vec3 pow(vec3 x, vec3 y);"));
- s.append(TString("vec4 pow(vec4 x, vec4 y);"));
-
- s.append(TString("float exp(float x);"));
- s.append(TString("vec2 exp(vec2 x);"));
- s.append(TString("vec3 exp(vec3 x);"));
- s.append(TString("vec4 exp(vec4 x);"));
-
- s.append(TString("float log(float x);"));
- s.append(TString("vec2 log(vec2 x);"));
- s.append(TString("vec3 log(vec3 x);"));
- s.append(TString("vec4 log(vec4 x);"));
-
- s.append(TString("float exp2(float x);"));
- s.append(TString("vec2 exp2(vec2 x);"));
- s.append(TString("vec3 exp2(vec3 x);"));
- s.append(TString("vec4 exp2(vec4 x);"));
-
- s.append(TString("float log2(float x);"));
- s.append(TString("vec2 log2(vec2 x);"));
- s.append(TString("vec3 log2(vec3 x);"));
- s.append(TString("vec4 log2(vec4 x);"));
-
- s.append(TString("float sqrt(float x);"));
- s.append(TString("vec2 sqrt(vec2 x);"));
- s.append(TString("vec3 sqrt(vec3 x);"));
- s.append(TString("vec4 sqrt(vec4 x);"));
-
- s.append(TString("float inversesqrt(float x);"));
- s.append(TString("vec2 inversesqrt(vec2 x);"));
- s.append(TString("vec3 inversesqrt(vec3 x);"));
- s.append(TString("vec4 inversesqrt(vec4 x);"));
+ 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.
//
- s.append(TString("float abs(float x);"));
- s.append(TString("vec2 abs(vec2 x);"));
- s.append(TString("vec3 abs(vec3 x);"));
- s.append(TString("vec4 abs(vec4 x);"));
-
- s.append(TString("float sign(float x);"));
- s.append(TString("vec2 sign(vec2 x);"));
- s.append(TString("vec3 sign(vec3 x);"));
- s.append(TString("vec4 sign(vec4 x);"));
-
- s.append(TString("float floor(float x);"));
- s.append(TString("vec2 floor(vec2 x);"));
- s.append(TString("vec3 floor(vec3 x);"));
- s.append(TString("vec4 floor(vec4 x);"));
-
- s.append(TString("float ceil(float x);"));
- s.append(TString("vec2 ceil(vec2 x);"));
- s.append(TString("vec3 ceil(vec3 x);"));
- s.append(TString("vec4 ceil(vec4 x);"));
-
- s.append(TString("float fract(float x);"));
- s.append(TString("vec2 fract(vec2 x);"));
- s.append(TString("vec3 fract(vec3 x);"));
- s.append(TString("vec4 fract(vec4 x);"));
-
- s.append(TString("float mod(float x, float y);"));
- s.append(TString("vec2 mod(vec2 x, float y);"));
- s.append(TString("vec3 mod(vec3 x, float y);"));
- s.append(TString("vec4 mod(vec4 x, float y);"));
- s.append(TString("vec2 mod(vec2 x, vec2 y);"));
- s.append(TString("vec3 mod(vec3 x, vec3 y);"));
- s.append(TString("vec4 mod(vec4 x, vec4 y);"));
-
- s.append(TString("float min(float x, float y);"));
- s.append(TString("vec2 min(vec2 x, float y);"));
- s.append(TString("vec3 min(vec3 x, float y);"));
- s.append(TString("vec4 min(vec4 x, float y);"));
- s.append(TString("vec2 min(vec2 x, vec2 y);"));
- s.append(TString("vec3 min(vec3 x, vec3 y);"));
- s.append(TString("vec4 min(vec4 x, vec4 y);"));
-
- s.append(TString("float max(float x, float y);"));
- s.append(TString("vec2 max(vec2 x, float y);"));
- s.append(TString("vec3 max(vec3 x, float y);"));
- s.append(TString("vec4 max(vec4 x, float y);"));
- s.append(TString("vec2 max(vec2 x, vec2 y);"));
- s.append(TString("vec3 max(vec3 x, vec3 y);"));
- s.append(TString("vec4 max(vec4 x, vec4 y);"));
-
- s.append(TString("float clamp(float x, float minVal, float maxVal);"));
- s.append(TString("vec2 clamp(vec2 x, float minVal, float maxVal);"));
- s.append(TString("vec3 clamp(vec3 x, float minVal, float maxVal);"));
- s.append(TString("vec4 clamp(vec4 x, float minVal, float maxVal);"));
- s.append(TString("vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);"));
- s.append(TString("vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);"));
- s.append(TString("vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);"));
-
- s.append(TString("float mix(float x, float y, float a);"));
- s.append(TString("vec2 mix(vec2 x, vec2 y, float a);"));
- s.append(TString("vec3 mix(vec3 x, vec3 y, float a);"));
- s.append(TString("vec4 mix(vec4 x, vec4 y, float a);"));
- s.append(TString("vec2 mix(vec2 x, vec2 y, vec2 a);"));
- s.append(TString("vec3 mix(vec3 x, vec3 y, vec3 a);"));
- s.append(TString("vec4 mix(vec4 x, vec4 y, vec4 a);"));
-
- s.append(TString("float step(float edge, float x);"));
- s.append(TString("vec2 step(vec2 edge, vec2 x);"));
- s.append(TString("vec3 step(vec3 edge, vec3 x);"));
- s.append(TString("vec4 step(vec4 edge, vec4 x);"));
- s.append(TString("vec2 step(float edge, vec2 x);"));
- s.append(TString("vec3 step(float edge, vec3 x);"));
- s.append(TString("vec4 step(float edge, vec4 x);"));
-
- s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
- s.append(TString("vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);"));
- s.append(TString("vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);"));
- s.append(TString("vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);"));
- s.append(TString("vec2 smoothstep(float edge0, float edge1, vec2 x);"));
- s.append(TString("vec3 smoothstep(float edge0, float edge1, vec3 x);"));
- s.append(TString("vec4 smoothstep(float edge0, float edge1, vec4 x);"));
+ 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.
//
- s.append(TString("float length(float x);"));
- s.append(TString("float length(vec2 x);"));
- s.append(TString("float length(vec3 x);"));
- s.append(TString("float length(vec4 x);"));
-
- s.append(TString("float distance(float p0, float p1);"));
- s.append(TString("float distance(vec2 p0, vec2 p1);"));
- s.append(TString("float distance(vec3 p0, vec3 p1);"));
- s.append(TString("float distance(vec4 p0, vec4 p1);"));
-
- s.append(TString("float dot(float x, float y);"));
- s.append(TString("float dot(vec2 x, vec2 y);"));
- s.append(TString("float dot(vec3 x, vec3 y);"));
- s.append(TString("float dot(vec4 x, vec4 y);"));
-
- s.append(TString("vec3 cross(vec3 x, vec3 y);"));
- s.append(TString("float normalize(float x);"));
- s.append(TString("vec2 normalize(vec2 x);"));
- s.append(TString("vec3 normalize(vec3 x);"));
- s.append(TString("vec4 normalize(vec4 x);"));
-
- s.append(TString("float faceforward(float N, float I, float Nref);"));
- s.append(TString("vec2 faceforward(vec2 N, vec2 I, vec2 Nref);"));
- s.append(TString("vec3 faceforward(vec3 N, vec3 I, vec3 Nref);"));
- s.append(TString("vec4 faceforward(vec4 N, vec4 I, vec4 Nref);"));
-
- s.append(TString("float reflect(float I, float N);"));
- s.append(TString("vec2 reflect(vec2 I, vec2 N);"));
- s.append(TString("vec3 reflect(vec3 I, vec3 N);"));
- s.append(TString("vec4 reflect(vec4 I, vec4 N);"));
-
- s.append(TString("float refract(float I, float N, float eta);"));
- s.append(TString("vec2 refract(vec2 I, vec2 N, float eta);"));
- s.append(TString("vec3 refract(vec3 I, vec3 N, float eta);"));
- s.append(TString("vec4 refract(vec4 I, vec4 N, float eta);"));
+ 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.
//
- s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
- s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
- s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
+ 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.
//
- s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
- s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
- s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "lessThan", float2, float2);
+ symbolTable.insertBuiltIn(bool3, "lessThan", float3, float3);
+ symbolTable.insertBuiltIn(bool4, "lessThan", float4, float4);
- s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
- s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
- s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "lessThan", int2, int2);
+ symbolTable.insertBuiltIn(bool3, "lessThan", int3, int3);
+ symbolTable.insertBuiltIn(bool4, "lessThan", int4, int4);
- s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "lessThanEqual", float2, float2);
+ symbolTable.insertBuiltIn(bool3, "lessThanEqual", float3, float3);
+ symbolTable.insertBuiltIn(bool4, "lessThanEqual", float4, float4);
- s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
- s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
- s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "lessThanEqual", int2, int2);
+ symbolTable.insertBuiltIn(bool3, "lessThanEqual", int3, int3);
+ symbolTable.insertBuiltIn(bool4, "lessThanEqual", int4, int4);
- s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "greaterThan", float2, float2);
+ symbolTable.insertBuiltIn(bool3, "greaterThan", float3, float3);
+ symbolTable.insertBuiltIn(bool4, "greaterThan", float4, float4);
- s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
- s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
- s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "greaterThan", int2, int2);
+ symbolTable.insertBuiltIn(bool3, "greaterThan", int3, int3);
+ symbolTable.insertBuiltIn(bool4, "greaterThan", int4, int4);
- s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "greaterThanEqual", float2, float2);
+ symbolTable.insertBuiltIn(bool3, "greaterThanEqual", float3, float3);
+ symbolTable.insertBuiltIn(bool4, "greaterThanEqual", float4, float4);
- s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
- s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
- s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "greaterThanEqual", int2, int2);
+ symbolTable.insertBuiltIn(bool3, "greaterThanEqual", int3, int3);
+ symbolTable.insertBuiltIn(bool4, "greaterThanEqual", int4, int4);
- s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "equal", float2, float2);
+ symbolTable.insertBuiltIn(bool3, "equal", float3, float3);
+ symbolTable.insertBuiltIn(bool4, "equal", float4, float4);
- s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
- s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
- s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "equal", int2, int2);
+ symbolTable.insertBuiltIn(bool3, "equal", int3, int3);
+ symbolTable.insertBuiltIn(bool4, "equal", int4, int4);
- s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
- s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
- s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "equal", bool2, bool2);
+ symbolTable.insertBuiltIn(bool3, "equal", bool3, bool3);
+ symbolTable.insertBuiltIn(bool4, "equal", bool4, bool4);
- s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "notEqual", float2, float2);
+ symbolTable.insertBuiltIn(bool3, "notEqual", float3, float3);
+ symbolTable.insertBuiltIn(bool4, "notEqual", float4, float4);
- s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
- s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
- s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
+ symbolTable.insertBuiltIn(bool2, "notEqual", int2, int2);
+ symbolTable.insertBuiltIn(bool3, "notEqual", int3, int3);
+ symbolTable.insertBuiltIn(bool4, "notEqual", int4, int4);
- s.append(TString("bool any(bvec2 x);"));
- s.append(TString("bool any(bvec3 x);"));
- s.append(TString("bool any(bvec4 x);"));
+ symbolTable.insertBuiltIn(bool2, "notEqual", bool2, bool2);
+ symbolTable.insertBuiltIn(bool3, "notEqual", bool3, bool3);
+ symbolTable.insertBuiltIn(bool4, "notEqual", bool4, bool4);
- s.append(TString("bool all(bvec2 x);"));
- s.append(TString("bool all(bvec3 x);"));
- s.append(TString("bool all(bvec4 x);"));
-
- s.append(TString("bvec2 not(bvec2 x);"));
- s.append(TString("bvec3 not(bvec3 x);"));
- s.append(TString("bvec4 not(bvec4 x);"));
-
- //
- // Texture Functions.
- //
- s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
- s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
-
- if (resources.OES_EGL_image_external) {
- s.append(TString("vec4 texture2D(samplerExternalOES sampler, vec2 coord);"));
- s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec3 coord);"));
- s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec4 coord);"));
- }
+ symbolTable.insertBuiltIn(bool1, "any", bool2);
+ symbolTable.insertBuiltIn(bool1, "any", bool3);
+ symbolTable.insertBuiltIn(bool1, "any", bool4);
- if (resources.ARB_texture_rectangle) {
- s.append(TString("vec4 texture2DRect(sampler2DRect sampler, vec2 coord);"));
- s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec3 coord);"));
- s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec4 coord);"));
- }
+ symbolTable.insertBuiltIn(bool1, "all", bool2);
+ symbolTable.insertBuiltIn(bool1, "all", bool3);
+ symbolTable.insertBuiltIn(bool1, "all", bool4);
- //
- // Noise functions.
- //
- //s.append(TString("float noise1(float x);"));
- //s.append(TString("float noise1(vec2 x);"));
- //s.append(TString("float noise1(vec3 x);"));
- //s.append(TString("float noise1(vec4 x);"));
-
- //s.append(TString("vec2 noise2(float x);"));
- //s.append(TString("vec2 noise2(vec2 x);"));
- //s.append(TString("vec2 noise2(vec3 x);"));
- //s.append(TString("vec2 noise2(vec4 x);"));
-
- //s.append(TString("vec3 noise3(float x);"));
- //s.append(TString("vec3 noise3(vec2 x);"));
- //s.append(TString("vec3 noise3(vec3 x);"));
- //s.append(TString("vec3 noise3(vec4 x);"));
-
- //s.append(TString("vec4 noise4(float x);"));
- //s.append(TString("vec4 noise4(vec2 x);"));
- //s.append(TString("vec4 noise4(vec3 x);"));
- //s.append(TString("vec4 noise4(vec4 x);"));
-
- return s;
-}
+ symbolTable.insertBuiltIn(bool2, "not", bool2);
+ symbolTable.insertBuiltIn(bool3, "not", bool3);
+ symbolTable.insertBuiltIn(bool4, "not", bool4);
-//============================================================================
-//
-// Prototypes for built-in functions seen by vertex shaders only.
-//
-//============================================================================
-static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources)
-{
- TString s;
+ TType *sampler2D = new TType(EbtSampler2D, EbpUndefined, EvqGlobal, 1);
+ TType *samplerCube = new TType(EbtSamplerCube, EbpUndefined, EvqGlobal, 1);
//
- // Geometric Functions.
+ // Texture Functions for GLSL ES 1.0
//
- //s.append(TString("vec4 ftransform();"));
+ symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, float2);
+ symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float3);
+ symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, float4);
+ symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, float3);
- //
- // Texture Functions.
- //
- s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
- s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
- s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
- s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+ if (resources.OES_EGL_image_external)
+ {
+ TType *samplerExternalOES = new TType(EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1);
- return s;
-}
+ symbolTable.insertBuiltIn(float4, "texture2D", samplerExternalOES, float2);
+ symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float3);
+ symbolTable.insertBuiltIn(float4, "texture2DProj", samplerExternalOES, float4);
+ }
-//============================================================================
-//
-// Prototypes for built-in functions seen by fragment shaders only.
-//
-//============================================================================
-static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources)
-{
- TString s;
+ if (resources.ARB_texture_rectangle)
+ {
+ TType *sampler2DRect = new TType(EbtSampler2DRect, EbpUndefined, EvqGlobal, 1);
- //
- // Texture Functions.
- //
- s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
- s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
-
- if (resources.OES_standard_derivatives) {
- s.append(TString("float dFdx(float p);"));
- s.append(TString("vec2 dFdx(vec2 p);"));
- s.append(TString("vec3 dFdx(vec3 p);"));
- s.append(TString("vec4 dFdx(vec4 p);"));
-
- s.append(TString("float dFdy(float p);"));
- s.append(TString("vec2 dFdy(vec2 p);"));
- s.append(TString("vec3 dFdy(vec3 p);"));
- s.append(TString("vec4 dFdy(vec4 p);"));
-
- s.append(TString("float fwidth(float p);"));
- s.append(TString("vec2 fwidth(vec2 p);"));
- s.append(TString("vec3 fwidth(vec3 p);"));
- s.append(TString("vec4 fwidth(vec4 p);"));
+ symbolTable.insertBuiltIn(float4, "texture2DRect", sampler2DRect, float2);
+ symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float3);
+ symbolTable.insertBuiltIn(float4, "texture2DRectProj", sampler2DRect, float4);
}
- return s;
-}
+ 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);
+ }
+ }
-//============================================================================
-//
-// Standard uniforms.
-//
-//============================================================================
-static TString StandardUniforms()
-{
- TString s;
+ 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
//
- s.append(TString("struct gl_DepthRangeParameters {"));
- s.append(TString(" highp float near;")); // n
- s.append(TString(" highp float far;")); // f
- s.append(TString(" highp float diff;")); // f - n
- s.append(TString("};"));
- s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
-
- return s;
-}
-
-//============================================================================
-//
-// Default precision for vertex shaders.
-//
-//============================================================================
-static TString DefaultPrecisionVertex()
-{
- TString s;
-
- s.append(TString("precision highp int;"));
- s.append(TString("precision highp float;"));
-
- return s;
-}
-
-//============================================================================
-//
-// Default precision for fragment shaders.
-//
-//============================================================================
-static TString DefaultPrecisionFragment()
-{
- TString s;
+ 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);
- s.append(TString("precision mediump int;"));
- // No default precision for float in fragment shaders
-
- return s;
-}
-
-//============================================================================
-//
-// Implementation dependent built-in constants.
-//
-//============================================================================
-static TString BuiltInConstants(ShShaderSpec spec, const ShBuiltInResources &resources)
-{
- TStringStream s;
-
- s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";";
- s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";";
-
- s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";";
- s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";";
- s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";";
- s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";";
- s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";";
+ //
+ // 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)
- s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";";
-
- return s.str();
-}
-
-void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec,
- const ShBuiltInResources& resources)
-{
- switch (type) {
- case SH_FRAGMENT_SHADER:
- builtInStrings.push_back(DefaultPrecisionFragment());
- builtInStrings.push_back(BuiltInFunctionsCommon(resources));
- builtInStrings.push_back(BuiltInFunctionsFragment(resources));
- builtInStrings.push_back(StandardUniforms());
- break;
-
- case SH_VERTEX_SHADER:
- builtInStrings.push_back(DefaultPrecisionVertex());
- builtInStrings.push_back(BuiltInFunctionsCommon(resources));
- builtInStrings.push_back(BuiltInFunctionsVertex(resources));
- builtInStrings.push_back(StandardUniforms());
- break;
-
- default: assert(false && "Language not supported");
+ {
+ symbolTable.insertConstInt("gl_MaxDrawBuffers", resources.MaxDrawBuffers);
}
-
- builtInStrings.push_back(BuiltInConstants(spec, resources));
}
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
- const ShBuiltInResources& resources,
- TSymbolTable& symbolTable)
+ const ShBuiltInResources &resources,
+ TSymbolTable &symbolTable)
{
//
// First, insert some special built-in variables that are not in
@@ -539,6 +439,10 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
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)));
@@ -560,8 +464,6 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
// expected to be resolved through a library of functions, versus as
// operations.
//
- symbolTable.relateToOperator("not", EOpVectorLogicalNot);
-
symbolTable.relateToOperator("matrixCompMult", EOpMul);
symbolTable.relateToOperator("equal", EOpVectorEqual);
@@ -612,6 +514,7 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
symbolTable.relateToOperator("any", EOpAny);
symbolTable.relateToOperator("all", EOpAll);
+ symbolTable.relateToOperator("not", EOpVectorLogicalNot);
// Map language-specific operators.
switch(type) {
@@ -656,4 +559,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
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/src/3rdparty/angle/src/compiler/Initialize.h b/src/3rdparty/angle/src/compiler/Initialize.h
index 8b0adc6b4c..4aa13466ac 100644
--- a/src/3rdparty/angle/src/compiler/Initialize.h
+++ b/src/3rdparty/angle/src/compiler/Initialize.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.
//
@@ -11,19 +11,7 @@
#include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h"
-typedef TVector<TString> TBuiltInStrings;
-
-class TBuiltIns {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
- void initialize(ShShaderType type, ShShaderSpec spec,
- const ShBuiltInResources& resources);
- const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
-
-protected:
- TBuiltInStrings builtInStrings;
-};
+void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
const ShBuiltInResources& resources,
diff --git a/src/3rdparty/angle/src/compiler/InitializeDll.cpp b/src/3rdparty/angle/src/compiler/InitializeDll.cpp
index 8763cfeea8..6c7f27fced 100644
--- a/src/3rdparty/angle/src/compiler/InitializeDll.cpp
+++ b/src/3rdparty/angle/src/compiler/InitializeDll.cpp
@@ -10,25 +10,8 @@
#include "compiler/InitializeParseContext.h"
#include "compiler/osinclude.h"
-OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
-
bool InitProcess()
{
- if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
- //
- // Function is re-entrant.
- //
- return true;
- }
-
- ThreadInitializeIndex = OS_AllocTLSIndex();
-
- if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
- return false;
- }
-
-
if (!InitializePoolIndex()) {
assert(0 && "InitProcess(): Failed to initalize global pool");
return false;
@@ -39,77 +22,11 @@ bool InitProcess()
return false;
}
- return InitThread();
-}
-
-bool DetachProcess()
-{
- bool success = true;
-
- if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
- return true;
-
- success = DetachThread();
-
- if (!FreeParseContextIndex())
- success = false;
-
- FreePoolIndex();
-
- OS_FreeTLSIndex(ThreadInitializeIndex);
- ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
-
- return success;
-}
-
-bool InitThread()
-{
- //
- // This function is re-entrant
- //
- if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitThread(): Process hasn't been initalised.");
- return false;
- }
-
- if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
- return true;
-
- InitializeGlobalPools();
-
- if (!InitializeGlobalParseContext())
- return false;
-
- if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
- assert(0 && "InitThread(): Unable to set init flag.");
- return false;
- }
-
return true;
}
-bool DetachThread()
+void DetachProcess()
{
- bool success = true;
-
- if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
- return true;
-
- //
- // Function is re-entrant and this thread may not have been initalised.
- //
- if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
- if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
- assert(0 && "DetachThread(): Unable to clear init flag.");
- success = false;
- }
-
- if (!FreeParseContext())
- success = false;
-
- FreeGlobalPools();
- }
-
- return success;
+ FreeParseContextIndex();
+ FreePoolIndex();
}
-
diff --git a/src/3rdparty/angle/src/compiler/InitializeDll.h b/src/3rdparty/angle/src/compiler/InitializeDll.h
index 857238eeae..43070cc3ff 100644
--- a/src/3rdparty/angle/src/compiler/InitializeDll.h
+++ b/src/3rdparty/angle/src/compiler/InitializeDll.h
@@ -7,10 +7,7 @@
#define __INITIALIZEDLL_H
bool InitProcess();
-bool DetachProcess();
-
-bool InitThread();
-bool DetachThread();
+void DetachProcess();
#endif // __INITIALIZEDLL_H
diff --git a/src/3rdparty/angle/src/compiler/InitializeGLPosition.cpp b/src/3rdparty/angle/src/compiler/InitializeGLPosition.cpp
new file mode 100644
index 0000000000..e0193e39d2
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/InitializeGLPosition.cpp
@@ -0,0 +1,61 @@
+//
+// 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/src/3rdparty/angle/src/compiler/InitializeGLPosition.h b/src/3rdparty/angle/src/compiler/InitializeGLPosition.h
new file mode 100644
index 0000000000..1b11075a13
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/InitializeGLPosition.h
@@ -0,0 +1,33 @@
+//
+// 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/src/3rdparty/angle/src/compiler/InitializeGlobals.h b/src/3rdparty/angle/src/compiler/InitializeGlobals.h
index 842a45281d..0715941424 100644
--- a/src/3rdparty/angle/src/compiler/InitializeGlobals.h
+++ b/src/3rdparty/angle/src/compiler/InitializeGlobals.h
@@ -7,8 +7,6 @@
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
#define __INITIALIZE_GLOBALS_INCLUDED_
-void InitializeGlobalPools();
-void FreeGlobalPools();
bool InitializePoolIndex();
void FreePoolIndex();
diff --git a/src/3rdparty/angle/src/compiler/InitializeParseContext.cpp b/src/3rdparty/angle/src/compiler/InitializeParseContext.cpp
index 1f40cf5800..dfab027330 100644
--- a/src/3rdparty/angle/src/compiler/InitializeParseContext.cpp
+++ b/src/3rdparty/angle/src/compiler/InitializeParseContext.cpp
@@ -12,85 +12,29 @@ OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex()
{
- if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
- assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
- return false;
- }
+ assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
- //
- // Allocate a TLS index.
- //
GlobalParseContextIndex = OS_AllocTLSIndex();
-
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
- return false;
- }
-
- return true;
+ return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
}
-bool FreeParseContextIndex()
+void FreeParseContextIndex()
{
- OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
-
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
- return false;
- }
+ assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+ OS_FreeTLSIndex(GlobalParseContextIndex);
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
-
- return OS_FreeTLSIndex(tlsiIndex);
-}
-
-bool InitializeGlobalParseContext()
-{
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
- return false;
- }
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
- if (lpParseContext != 0) {
- assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
- return false;
- }
-
- TThreadParseContext *lpThreadData = new TThreadParseContext();
- if (lpThreadData == 0) {
- assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
- return false;
- }
-
- lpThreadData->lpGlobalParseContext = 0;
- OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
-
- return true;
}
-bool FreeParseContext()
+void SetGlobalParseContext(TParseContext* context)
{
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "FreeParseContext(): Parse Context index not initalized");
- return false;
- }
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
- if (lpParseContext)
- delete lpParseContext;
-
- return true;
+ assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+ OS_SetTLSValue(GlobalParseContextIndex, context);
}
-TParseContextPointer& GetGlobalParseContext()
+TParseContext* GetGlobalParseContext()
{
- //
- // Minimal error checking for speed
- //
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
- return lpParseContext->lpGlobalParseContext;
+ assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+ return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
}
diff --git a/src/3rdparty/angle/src/compiler/InitializeParseContext.h b/src/3rdparty/angle/src/compiler/InitializeParseContext.h
index aa53b735d4..bffbab87d0 100644
--- a/src/3rdparty/angle/src/compiler/InitializeParseContext.h
+++ b/src/3rdparty/angle/src/compiler/InitializeParseContext.h
@@ -8,19 +8,10 @@
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
bool InitializeParseContextIndex();
-bool FreeParseContextIndex();
-
-bool InitializeGlobalParseContext();
-bool FreeParseContext();
+void FreeParseContextIndex();
struct TParseContext;
-typedef TParseContext* TParseContextPointer;
-extern TParseContextPointer& GetGlobalParseContext();
-#define GlobalParseContext GetGlobalParseContext()
-
-typedef struct TThreadParseContextRec
-{
- TParseContext *lpGlobalParseContext;
-} TThreadParseContext;
+extern void SetGlobalParseContext(TParseContext* context);
+extern TParseContext* GetGlobalParseContext();
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/src/3rdparty/angle/src/compiler/Intermediate.cpp b/src/3rdparty/angle/src/compiler/Intermediate.cpp
index edf279ef67..3b6622185d 100644
--- a/src/3rdparty/angle/src/compiler/Intermediate.cpp
+++ b/src/3rdparty/angle/src/compiler/Intermediate.cpp
@@ -131,7 +131,7 @@ const char* getOperatorString(TOperator op) {
//
// Returns the added node.
//
-TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
+TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc& line)
{
TIntermSymbol* node = new TIntermSymbol(id, name, type);
node->setLine(line);
@@ -144,7 +144,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
//
// Returns the added node.
//
-TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
+TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line, TSymbolTable& symbolTable)
{
switch (op) {
case EOpEqual:
@@ -200,8 +200,6 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// one and promote it to the right type.
//
TIntermBinary* node = new TIntermBinary(op);
- if (line == 0)
- line = right->getLine();
node->setLine(line);
node->setLeft(left);
@@ -230,15 +228,13 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
//
// Returns the added node.
//
-TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
{
//
// Like adding binary math, except the conversion can only go
// from right to left.
//
TIntermBinary* node = new TIntermBinary(op);
- if (line == 0)
- line = left->getLine();
node->setLine(line);
TIntermTyped* child = addConversion(op, left->getType(), right);
@@ -260,11 +256,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
// Returns the added node.
// The caller should set the type of the returned node.
//
-TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
+TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc& line)
{
TIntermBinary* node = new TIntermBinary(op);
- if (line == 0)
- line = index->getLine();
node->setLine(line);
node->setLeft(base);
node->setRight(index);
@@ -279,13 +273,13 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
//
// Returns the added node.
//
-TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc& line, TSymbolTable& symbolTable)
{
TIntermUnary* node;
TIntermTyped* child = childNode->getAsTyped();
if (child == 0) {
- infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+ infoSink.info.message(EPrefixInternalError, line, "Bad type in AddUnaryMath");
return 0;
}
@@ -348,8 +342,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
// Make a new node for the operator.
//
node = new TIntermUnary(op);
- if (line == 0)
- line = child->getLine();
node->setLine(line);
node->setOperand(child);
@@ -376,7 +368,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
// Returns an aggregate node, which could be the one passed in if
// it was already an aggregate but no operator was set.
//
-TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line)
+TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TSourceLoc& line)
{
TIntermAggregate* aggNode;
@@ -391,8 +383,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
//
aggNode = new TIntermAggregate();
aggNode->getSequence().push_back(node);
- if (line == 0)
- line = node->getLine();
}
} else
aggNode = new TIntermAggregate();
@@ -401,8 +391,7 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
// Set the operator.
//
aggNode->setOp(op);
- if (line != 0)
- aggNode->setLine(line);
+ aggNode->setLine(line);
return aggNode;
}
@@ -491,7 +480,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
return 0;
}
break;
@@ -500,7 +489,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
return 0;
}
break;
@@ -509,12 +498,12 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
return 0;
}
break;
default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion type");
return 0;
}
@@ -534,7 +523,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// Returns the resulting aggregate, unless 0 was passed in for
// both existing nodes.
//
-TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
+TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& line)
{
if (left == 0 && right == 0)
return 0;
@@ -551,8 +540,7 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
if (right)
aggNode->getSequence().push_back(right);
- if (line != 0)
- aggNode->setLine(line);
+ aggNode->setLine(line);
return aggNode;
}
@@ -562,18 +550,14 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
//
// Returns an aggregate, unless 0 was passed in for the existing node.
//
-TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
+TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& line)
{
if (node == 0)
return 0;
TIntermAggregate* aggNode = new TIntermAggregate;
aggNode->getSequence().push_back(node);
-
- if (line != 0)
- aggNode->setLine(line);
- else
- aggNode->setLine(node->getLine());
+ aggNode->setLine(line);
return aggNode;
}
@@ -585,7 +569,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin
//
// Returns the selection node created.
//
-TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
+TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& line)
{
//
// For compile time constant selections, prune the code and
@@ -606,7 +590,7 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
}
-TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
{
if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
return right;
@@ -626,7 +610,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
//
// Returns the selection node created, or 0 if one could not be.
//
-TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
+TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& line)
{
//
// Get compatible types.
@@ -669,7 +653,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Returns the constant union node created.
//
-TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, TSourceLoc line)
+TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, const TSourceLoc& line)
{
TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
node->setLine(line);
@@ -677,7 +661,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayP
return node;
}
-TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& line)
{
TIntermAggregate* node = new TIntermAggregate(EOpSequence);
@@ -700,7 +684,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
//
// Create loop nodes.
//
-TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
+TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, const TSourceLoc& line)
{
TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
node->setLine(line);
@@ -711,12 +695,12 @@ TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTy
//
// Add branches.
//
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& line)
{
return addBranch(branchOp, 0, line);
}
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& line)
{
TIntermBranch* node = new TIntermBranch(branchOp, expression);
node->setLine(line);
@@ -861,7 +845,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
{
// This function only handles scalars, vectors, and matrices.
if (left->isArray() || right->isArray()) {
- infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operation for arrays");
return false;
}
@@ -966,7 +950,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
}
} else {
- infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
return false;
}
break;
@@ -995,7 +979,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
}
} else {
- infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
return false;
}
break;
@@ -1035,23 +1019,22 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{
- const TTypeList* fields = leftNodeType.getStruct();
+ const TFieldList& fields = leftNodeType.getStruct()->fields();
- size_t structSize = fields->size();
- int index = 0;
+ size_t structSize = fields.size();
+ size_t index = 0;
for (size_t j = 0; j < structSize; j++) {
- int size = (*fields)[j].type->getObjectSize();
- for (int i = 0; i < size; i++) {
- if ((*fields)[j].type->getBasicType() == EbtStruct) {
- if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index]))
+ 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]))
return false;
} else {
if (leftUnionArray[index] != rightUnionArray[index])
return false;
index++;
}
-
}
}
return true;
@@ -1063,10 +1046,10 @@ bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray,
TType typeWithoutArrayness = leftNodeType;
typeWithoutArrayness.clearArrayness();
- int arraySize = leftNodeType.getArraySize();
+ size_t arraySize = leftNodeType.getArraySize();
- for (int i = 0; i < arraySize; ++i) {
- int offset = typeWithoutArrayness.getObjectSize() * i;
+ for (size_t i = 0; i < arraySize; ++i) {
+ size_t offset = typeWithoutArrayness.getObjectSize() * i;
if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
return false;
}
@@ -1086,7 +1069,7 @@ bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray,
TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
{
ConstantUnion *unionArray = getUnionArrayPointer();
- int objectSize = getType().getObjectSize();
+ size_t objectSize = getType().getObjectSize();
if (constantNode) { // binary operations
TIntermConstantUnion *node = constantNode->getAsConstantUnion();
@@ -1096,13 +1079,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
// for a case like float f = 1.2 + vec4(2,3,4,5);
if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
rightUnionArray = new ConstantUnion[objectSize];
- for (int i = 0; i < objectSize; ++i)
+ for (size_t i = 0; i < objectSize; ++i)
rightUnionArray[i] = *node->getUnionArrayPointer();
returnType = getType();
} 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 (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
+ for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
unionArray[i] = *getUnionArrayPointer();
returnType = node->getType();
objectSize = constantNode->getType().getObjectSize();
@@ -1116,14 +1099,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpAdd:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
- for (int i = 0; i < objectSize; i++)
+ 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 (int i = 0; i < objectSize; i++)
+ for (size_t i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] - rightUnionArray[i];
}
break;
@@ -1133,13 +1116,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpMatrixTimesScalar:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
- for (int i = 0; i < objectSize; i++)
+ 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, "Constant Folding cannot be done for matrix multiply", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix multiply");
return 0;
}
{// support MSVC++6.0
@@ -1158,11 +1141,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpDiv:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
- for (int i = 0; i < objectSize; i++) {
+ for (size_t i = 0; i < objectSize; i++) {
switch (getType().getBasicType()) {
case EbtFloat:
if (rightUnionArray[i] == 0.0f) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+ 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());
@@ -1170,13 +1153,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EbtInt:
if (rightUnionArray[i] == 0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+ 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, "Constant folding cannot be done for \"/\"", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Constant folding cannot be done for \"/\"");
return 0;
}
}
@@ -1185,7 +1168,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpMatrixTimesVector:
if (node->getBasicType() != EbtFloat) {
- infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix times vector");
return 0;
}
tempConstArray = new ConstantUnion[getNominalSize()];
@@ -1206,7 +1189,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpVectorTimesMatrix:
if (getType().getBasicType() != EbtFloat) {
- infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for vector times matrix");
return 0;
}
@@ -1224,7 +1207,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
- for (int i = 0; i < objectSize; i++)
+ for (size_t i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] && rightUnionArray[i];
}
break;
@@ -1232,7 +1215,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
- for (int i = 0; i < objectSize; i++)
+ for (size_t i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] || rightUnionArray[i];
}
break;
@@ -1240,7 +1223,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpLogicalXor:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
- for (int i = 0; i < objectSize; i++)
+ 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");
@@ -1286,7 +1269,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
boolNodeFlag = true;
} else {
- for (int i = 0; i < objectSize; i++) {
+ for (size_t i = 0; i < objectSize; i++) {
if (unionArray[i] != rightUnionArray[i]) {
boolNodeFlag = true;
break; // break out of for loop
@@ -1312,7 +1295,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
boolNodeFlag = true;
} else {
- for (int i = 0; i < objectSize; i++) {
+ for (size_t i = 0; i < objectSize; i++) {
if (unionArray[i] == rightUnionArray[i]) {
boolNodeFlag = true;
break; // break out of for loop
@@ -1334,7 +1317,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
return tempNode;
default:
- infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operator for constant folding");
return 0;
}
tempNode = new TIntermConstantUnion(tempConstArray, returnType);
@@ -1347,14 +1330,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
//
TIntermConstantUnion *newNode = 0;
ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
- for (int i = 0; i < objectSize; i++) {
+ 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, "Unary operation not folded into constant", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return 0;
}
break;
@@ -1362,7 +1345,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
switch (getType().getBasicType()) {
case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
default:
- infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return 0;
}
break;
@@ -1378,11 +1361,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
{
- int size = node->getType().getObjectSize();
+ size_t size = node->getType().getObjectSize();
ConstantUnion *leftUnionArray = new ConstantUnion[size];
- for (int i=0; i < size; i++) {
+ for (size_t i = 0; i < size; i++) {
switch (promoteTo) {
case EbtFloat:
@@ -1397,7 +1380,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
break;
default:
- infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
return 0;
}
break;
@@ -1413,7 +1396,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
break;
default:
- infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
return 0;
}
break;
@@ -1429,13 +1412,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
break;
default:
- infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
return 0;
}
break;
default:
- infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Incorrect data type found");
return 0;
}
diff --git a/src/3rdparty/angle/src/compiler/OutputGLSL.cpp b/src/3rdparty/angle/src/compiler/OutputGLSL.cpp
index 206f403408..10a451c0d7 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputGLSL.cpp
@@ -19,3 +19,17 @@ 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/src/3rdparty/angle/src/compiler/OutputGLSL.h b/src/3rdparty/angle/src/compiler/OutputGLSL.h
index 199b6f3e46..fa68ac8103 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSL.h
+++ b/src/3rdparty/angle/src/compiler/OutputGLSL.h
@@ -20,6 +20,7 @@ public:
protected:
virtual bool writeVariablePrecision(TPrecision);
+ virtual void visitSymbol(TIntermSymbol* node);
};
#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
index 1b9a10deaa..d677c75633 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
@@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
out << type.getQualifierString() << " ";
// Declare the struct if we have not done so already.
- if ((type.getBasicType() == EbtStruct) &&
- (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
+ if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
{
- out << "struct " << hashName(type.getTypeName()) << "{\n";
- const TTypeList* structure = type.getStruct();
- ASSERT(structure != NULL);
- for (size_t i = 0; i < structure->size(); ++i)
- {
- const TType* fieldType = (*structure)[i].type;
- ASSERT(fieldType != NULL);
- if (writeVariablePrecision(fieldType->getPrecision()))
- out << " ";
- out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
- if (fieldType->isArray())
- out << arrayBrackets(*fieldType);
- out << ";\n";
- }
- out << "}";
- mDeclaredStructs.insert(type.getTypeName());
+ declareStruct(type.getStruct());
}
else
{
@@ -138,24 +122,25 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
if (type.getBasicType() == EbtStruct)
{
- out << hashName(type.getTypeName()) << "(";
- const TTypeList* structure = type.getStruct();
- ASSERT(structure != NULL);
- for (size_t i = 0; i < structure->size(); ++i)
+ 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 = (*structure)[i].type;
+ const TType* fieldType = fields[i]->type();
ASSERT(fieldType != NULL);
pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
- if (i != structure->size() - 1) out << ", ";
+ if (i != fields.size() - 1) out << ", ";
}
out << ")";
}
else
{
- int size = type.getObjectSize();
+ size_t size = type.getObjectSize();
bool writeType = size > 1;
if (writeType) out << getTypeName(type) << "(";
- for (int i = 0; i < size; ++i, ++pConstUnion)
+ for (size_t i = 0; i < size; ++i, ++pConstUnion)
{
switch (pConstUnion->getType())
{
@@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
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 << ".";
- // TODO(alokp): ASSERT
- TString fieldName = node->getType().getFieldName();
+ const TStructure* structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
+ const TField* field = structure->fields()[index->getIConst(0)];
- const TType& structType = node->getLeft()->getType();
- if (!mSymbolTable.findBuiltIn(structType.getTypeName()))
+ TString fieldName = field->name();
+ if (!mSymbolTable.findBuiltIn(structure->name()))
fieldName = hashName(fieldName);
out << fieldName;
@@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{
const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct);
- out << hashName(type.getTypeName()) << "(";
+ out << hashName(type.getStruct()->name()) << "(";
}
else if (visit == InVisit)
{
@@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
else
{
if (type.getBasicType() == EbtStruct)
- out << hashName(type.getTypeName());
+ out << hashName(type.getStruct()->name());
else
out << type.getBasicString();
}
@@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
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/src/3rdparty/angle/src/compiler/OutputGLSLBase.h b/src/3rdparty/angle/src/compiler/OutputGLSLBase.h
index c9f72d5631..df4ad68c2c 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSLBase.h
+++ b/src/3rdparty/angle/src/compiler/OutputGLSLBase.h
@@ -52,6 +52,9 @@ protected:
TString hashFunctionName(const TString& mangled_name);
private:
+ bool structDeclared(const TStructure* structure) const;
+ void declareStruct(const TStructure* structure);
+
TInfoSinkBase& mObjSink;
bool mDeclaringVariables;
diff --git a/src/3rdparty/angle/src/compiler/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/OutputHLSL.cpp
index f6a984148b..79a373ebab 100644
--- a/src/3rdparty/angle/src/compiler/OutputHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputHLSL.cpp
@@ -55,6 +55,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesPointCoord = false;
mUsesFrontFacing = false;
mUsesPointSize = false;
+ mUsesFragDepth = false;
mUsesXor = false;
mUsesMod1 = false;
mUsesMod2v = false;
@@ -67,18 +68,6 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesFaceforward2 = false;
mUsesFaceforward3 = false;
mUsesFaceforward4 = false;
- mUsesEqualMat2 = false;
- mUsesEqualMat3 = false;
- mUsesEqualMat4 = false;
- mUsesEqualVec2 = false;
- mUsesEqualVec3 = false;
- mUsesEqualVec4 = false;
- mUsesEqualIVec2 = false;
- mUsesEqualIVec3 = false;
- mUsesEqualIVec4 = false;
- mUsesEqualBVec2 = false;
- mUsesEqualBVec3 = false;
- mUsesEqualBVec4 = false;
mUsesAtan2_1 = false;
mUsesAtan2_2 = false;
mUsesAtan2_3 = false;
@@ -210,9 +199,9 @@ void OutputHLSL::header()
if (shaderType == SH_FRAGMENT_SHADER)
{
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
- bool usingMRTExtension = iter != mContext.extensionBehavior().end() && iter->second == EBhEnable;
+ const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
- unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
+ const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
out << "// Varyings\n";
out << varyings;
@@ -230,6 +219,11 @@ void OutputHLSL::header()
}
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";
@@ -844,6 +838,16 @@ void OutputHLSL::header()
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"
@@ -980,108 +984,6 @@ void OutputHLSL::header()
"\n";
}
- if (mUsesEqualMat2)
- {
- out << "bool equal(float2x2 m, float2x2 n)\n"
- "{\n"
- " return m[0][0] == n[0][0] && m[0][1] == n[0][1] &&\n"
- " m[1][0] == n[1][0] && m[1][1] == n[1][1];\n"
- "}\n";
- }
-
- if (mUsesEqualMat3)
- {
- out << "bool equal(float3x3 m, float3x3 n)\n"
- "{\n"
- " return m[0][0] == n[0][0] && m[0][1] == n[0][1] && m[0][2] == n[0][2] &&\n"
- " m[1][0] == n[1][0] && m[1][1] == n[1][1] && m[1][2] == n[1][2] &&\n"
- " m[2][0] == n[2][0] && m[2][1] == n[2][1] && m[2][2] == n[2][2];\n"
- "}\n";
- }
-
- if (mUsesEqualMat4)
- {
- out << "bool equal(float4x4 m, float4x4 n)\n"
- "{\n"
- " return m[0][0] == n[0][0] && m[0][1] == n[0][1] && m[0][2] == n[0][2] && m[0][3] == n[0][3] &&\n"
- " m[1][0] == n[1][0] && m[1][1] == n[1][1] && m[1][2] == n[1][2] && m[1][3] == n[1][3] &&\n"
- " m[2][0] == n[2][0] && m[2][1] == n[2][1] && m[2][2] == n[2][2] && m[2][3] == n[2][3] &&\n"
- " m[3][0] == n[3][0] && m[3][1] == n[3][1] && m[3][2] == n[3][2] && m[3][3] == n[3][3];\n"
- "}\n";
- }
-
- if (mUsesEqualVec2)
- {
- out << "bool equal(float2 v, float2 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y;\n"
- "}\n";
- }
-
- if (mUsesEqualVec3)
- {
- out << "bool equal(float3 v, float3 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y && v.z == u.z;\n"
- "}\n";
- }
-
- if (mUsesEqualVec4)
- {
- out << "bool equal(float4 v, float4 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;\n"
- "}\n";
- }
-
- if (mUsesEqualIVec2)
- {
- out << "bool equal(int2 v, int2 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y;\n"
- "}\n";
- }
-
- if (mUsesEqualIVec3)
- {
- out << "bool equal(int3 v, int3 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y && v.z == u.z;\n"
- "}\n";
- }
-
- if (mUsesEqualIVec4)
- {
- out << "bool equal(int4 v, int4 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;\n"
- "}\n";
- }
-
- if (mUsesEqualBVec2)
- {
- out << "bool equal(bool2 v, bool2 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y;\n"
- "}\n";
- }
-
- if (mUsesEqualBVec3)
- {
- out << "bool equal(bool3 v, bool3 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y && v.z == u.z;\n"
- "}\n";
- }
-
- if (mUsesEqualBVec4)
- {
- out << "bool equal(bool4 v, bool4 u)\n"
- "{\n"
- " return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;\n"
- "}\n";
- }
-
if (mUsesAtan2_1)
{
out << "float atanyx(float y, float x)\n"
@@ -1166,6 +1068,11 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesPointSize = true;
out << name;
}
+ else if (name == "gl_FragDepthEXT")
+ {
+ mUsesFragDepth = true;
+ out << "gl_Depth";
+ }
else
{
TQualifier qualifier = node->getQualifier();
@@ -1275,7 +1182,10 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
case EOpIndexDirectStruct:
if (visit == InVisit)
{
- out << "." + decorateField(node->getType().getFieldName(), node->getLeft()->getType());
+ 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;
}
@@ -1344,18 +1254,18 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
out << "!(";
}
- const TTypeList *fields = node->getLeft()->getType().getStruct();
+ const TFieldList &fields = node->getLeft()->getType().getStruct()->fields();
- for (size_t i = 0; i < fields->size(); i++)
+ for (size_t i = 0; i < fields.size(); i++)
{
- const TType *fieldType = (*fields)[i].type;
+ const TField *field = fields[i];
node->getLeft()->traverse(this);
- out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()) + " == ";
+ out << "." + decorateField(field->name(), node->getLeft()->getType()) + " == ";
node->getRight()->traverse(this);
- out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType());
+ out << "." + decorateField(field->name(), node->getLeft()->getType());
- if (i < fields->size() - 1)
+ if (i < fields.size() - 1)
{
out << " && ";
}
@@ -1367,59 +1277,15 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
}
else
{
- if (node->getLeft()->isMatrix())
- {
- switch (node->getLeft()->getNominalSize())
- {
- case 2: mUsesEqualMat2 = true; break;
- case 3: mUsesEqualMat3 = true; break;
- case 4: mUsesEqualMat4 = true; break;
- default: UNREACHABLE();
- }
- }
- else if (node->getLeft()->isVector())
- {
- switch (node->getLeft()->getBasicType())
- {
- case EbtFloat:
- switch (node->getLeft()->getNominalSize())
- {
- case 2: mUsesEqualVec2 = true; break;
- case 3: mUsesEqualVec3 = true; break;
- case 4: mUsesEqualVec4 = true; break;
- default: UNREACHABLE();
- }
- break;
- case EbtInt:
- switch (node->getLeft()->getNominalSize())
- {
- case 2: mUsesEqualIVec2 = true; break;
- case 3: mUsesEqualIVec3 = true; break;
- case 4: mUsesEqualIVec4 = true; break;
- default: UNREACHABLE();
- }
- break;
- case EbtBool:
- switch (node->getLeft()->getNominalSize())
- {
- case 2: mUsesEqualBVec2 = true; break;
- case 3: mUsesEqualBVec3 = true; break;
- case 4: mUsesEqualBVec4 = true; break;
- default: UNREACHABLE();
- }
- break;
- default: UNREACHABLE();
- }
- }
- else UNREACHABLE();
+ ASSERT(node->getLeft()->isMatrix() || node->getLeft()->isVector());
if (node->getOp() == EOpEqual)
{
- outputTriplet(visit, "equal(", ", ", ")");
+ outputTriplet(visit, "all(", " == ", ")");
}
else
{
- outputTriplet(visit, "!equal(", ", ", ")");
+ outputTriplet(visit, "!all(", " == ", ")");
}
}
break;
@@ -1561,7 +1427,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (mInsideFunction)
{
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << "{\n";
mScopeDepth++;
@@ -1578,7 +1444,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
{
- outputLineDirective((*sit)->getLine());
+ outputLineDirective((*sit)->getLine().first_line);
traverseStatements(*sit);
@@ -1587,7 +1453,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (mInsideFunction)
{
- outputLineDirective(node->getEndLine());
+ outputLineDirective(node->getLine().last_line);
out << "}\n";
mScopeDepth--;
@@ -1605,7 +1471,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (variable->getType().getStruct())
{
- addConstructor(variable->getType(), scopedStruct(variable->getType().getTypeName()), NULL);
+ addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL);
}
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
@@ -1732,7 +1598,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (symbol->getType().getStruct())
{
- addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL);
+ addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL);
}
out << argumentString(symbol);
@@ -1993,8 +1859,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
outputTriplet(visit, "mat4(", ", ", ")");
break;
case EOpConstructStruct:
- addConstructor(node->getType(), scopedStruct(node->getType().getTypeName()), &node->getSequence());
- outputTriplet(visit, structLookup(node->getType().getTypeName()) + "_ctor(", ", ", ")");
+ 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;
@@ -2084,7 +1950,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
out << ")\n";
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << "{\n";
if (node->getTrueBlock())
@@ -2092,20 +1958,20 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
traverseStatements(node->getTrueBlock());
}
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << ";\n}\n";
if (node->getFalseBlock())
{
out << "else\n";
- outputLineDirective(node->getFalseBlock()->getLine());
+ outputLineDirective(node->getFalseBlock()->getLine().first_line);
out << "{\n";
- outputLineDirective(node->getFalseBlock()->getLine());
+ outputLineDirective(node->getFalseBlock()->getLine().first_line);
traverseStatements(node->getFalseBlock());
- outputLineDirective(node->getFalseBlock()->getLine());
+ outputLineDirective(node->getFalseBlock()->getLine().first_line);
out << ";\n}\n";
}
}
@@ -2141,7 +2007,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{
out << "{do\n";
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << "{\n";
}
else
@@ -2169,7 +2035,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
out << ")\n";
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << "{\n";
}
@@ -2178,12 +2044,12 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
traverseStatements(node->getBody());
}
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << ";}\n";
if (node->getType() == ELoopDoWhile)
{
- outputLineDirective(node->getCondition()->getLine());
+ outputLineDirective(node->getCondition()->getLine().first_line);
out << "while(\n";
node->getCondition()->traverse(this);
@@ -2455,7 +2321,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
out << increment;
out << ")\n";
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << "{\n";
if (node->getBody())
@@ -2463,7 +2329,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
node->getBody()->traverse(this);
}
- outputLineDirective(node->getLine());
+ outputLineDirective(node->getLine().first_line);
out << ";}\n";
if (!firstLoopFragment)
@@ -2565,22 +2431,23 @@ TString OutputHLSL::typeString(const TType &type)
{
if (type.getBasicType() == EbtStruct)
{
- if (type.getTypeName() != "")
+ const TString& typeName = type.getStruct()->name();
+ if (typeName != "")
{
- return structLookup(type.getTypeName());
+ return structLookup(typeName);
}
else // Nameless structure, define in place
{
- const TTypeList &fields = *type.getStruct();
+ const TFieldList &fields = type.getStruct()->fields();
TString string = "struct\n"
"{\n";
for (unsigned int i = 0; i < fields.size(); i++)
{
- const TType &field = *fields[i].type;
+ const TField *field = fields[i];
- string += " " + typeString(field) + " " + decorate(field.getFieldName()) + arrayString(field) + ";\n";
+ string += " " + typeString(*field->type()) + " " + decorate(field->name()) + arrayString(*field->type()) + ";\n";
}
string += "} ";
@@ -2674,11 +2541,12 @@ TString OutputHLSL::initializer(const TType &type)
{
TString string;
- for (int component = 0; component < type.getObjectSize(); component++)
+ size_t size = type.getObjectSize();
+ for (size_t component = 0; component < size; component++)
{
string += "0";
- if (component < type.getObjectSize() - 1)
+ if (component + 1 < size)
{
string += ", ";
}
@@ -2717,13 +2585,13 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
structure += "struct " + decorate(name) + "\n"
"{\n";
- const TTypeList &fields = *type.getStruct();
+ const TFieldList &fields = type.getStruct()->fields();
for (unsigned int i = 0; i < fields.size(); i++)
{
- const TType &field = *fields[i].type;
+ const TField *field = fields[i];
- structure += " " + typeString(field) + " " + decorateField(field.getFieldName(), type) + arrayString(field) + ";\n";
+ structure += " " + typeString(*field->type()) + " " + decorateField(field->name(), type) + arrayString(*field->type()) + ";\n";
}
structure += "};\n";
@@ -2735,7 +2603,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
for (unsigned int i = 0; i < fields.size(); i++)
{
- ctorParameters.push_back(*fields[i].type);
+ ctorParameters.push_back(*fields[i]->type());
}
}
else if (parameters)
@@ -2828,27 +2696,30 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
}
else
{
- int remainingComponents = ctorType.getObjectSize();
- int parameterIndex = 0;
+ size_t remainingComponents = ctorType.getObjectSize();
+ size_t parameterIndex = 0;
while (remainingComponents > 0)
{
const TType &parameter = ctorParameters[parameterIndex];
- bool moreParameters = parameterIndex < (int)ctorParameters.size() - 1;
+ const size_t parameterSize = parameter.getObjectSize();
+ bool moreParameters = parameterIndex + 1 < ctorParameters.size();
constructor += "x" + str(parameterIndex);
if (parameter.isScalar())
{
- remainingComponents -= parameter.getObjectSize();
+ ASSERT(parameterSize <= remainingComponents);
+ remainingComponents -= parameterSize;
}
else if (parameter.isVector())
{
- if (remainingComponents == parameter.getObjectSize() || moreParameters)
+ if (remainingComponents == parameterSize || moreParameters)
{
- remainingComponents -= parameter.getObjectSize();
+ ASSERT(parameterSize <= remainingComponents);
+ remainingComponents -= parameterSize;
}
- else if (remainingComponents < parameter.getNominalSize())
+ else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
{
switch (remainingComponents)
{
@@ -2865,9 +2736,10 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
}
else if (parameter.isMatrix() || parameter.getStruct())
{
- ASSERT(remainingComponents == parameter.getObjectSize() || moreParameters);
+ ASSERT(remainingComponents == parameterSize || moreParameters);
+ ASSERT(parameterSize <= remainingComponents);
- remainingComponents -= parameter.getObjectSize();
+ remainingComponents -= parameterSize;
}
else UNREACHABLE();
@@ -2904,17 +2776,17 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
if (type.getBasicType() == EbtStruct)
{
- out << structLookup(type.getTypeName()) + "_ctor(";
+ out << structLookup(type.getStruct()->name()) + "_ctor(";
- const TTypeList *structure = type.getStruct();
+ const TFieldList &fields = type.getStruct()->fields();
- for (size_t i = 0; i < structure->size(); i++)
+ for (size_t i = 0; i < fields.size(); i++)
{
- const TType *fieldType = (*structure)[i].type;
+ const TType *fieldType = fields[i]->type();
constUnion = writeConstantUnion(*fieldType, constUnion);
- if (i != structure->size() - 1)
+ if (i != fields.size() - 1)
{
out << ", ";
}
@@ -2924,7 +2796,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
}
else
{
- int size = type.getObjectSize();
+ size_t size = type.getObjectSize();
bool writeType = size > 1;
if (writeType)
@@ -2932,7 +2804,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
out << typeString(type) << "(";
}
- for (int i = 0; i < size; i++, constUnion++)
+ for (size_t i = 0; i < size; i++, constUnion++)
{
switch (constUnion->getType())
{
@@ -3021,7 +2893,7 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
TString OutputHLSL::decorateField(const TString &string, const TType &structure)
{
- if (structure.getTypeName().compare(0, 3, "gl_") != 0)
+ if (structure.getStruct()->name().compare(0, 3, "gl_") != 0)
{
return decorate(string);
}
@@ -3069,7 +2941,7 @@ int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
void OutputHLSL::declareUniform(const TType &type, const TString &name, int index)
{
- const TTypeList *structure = type.getStruct();
+ TStructure *structure = type.getStruct();
if (!structure)
{
@@ -3077,18 +2949,18 @@ void OutputHLSL::declareUniform(const TType &type, const TString &name, int inde
}
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 < structure->size(); j++)
+ for (size_t j = 0; j < fields.size(); j++)
{
- const TType &fieldType = *(*structure)[j].type;
- const TString &fieldName = fieldType.getFieldName();
-
- const TString uniformName = name + "[" + str(i) + "]." + fieldName;
+ const TType &fieldType = *fields[j]->type();
+ const TString uniformName = name + "[" + str(i) + "]." + fields[j]->name();
declareUniform(fieldType, uniformName, elementIndex);
elementIndex += fieldType.totalRegisterCount();
}
@@ -3098,12 +2970,10 @@ void OutputHLSL::declareUniform(const TType &type, const TString &name, int inde
{
int fieldIndex = index;
- for (size_t i = 0; i < structure->size(); i++)
+ for (size_t i = 0; i < fields.size(); i++)
{
- const TType &fieldType = *(*structure)[i].type;
- const TString &fieldName = fieldType.getFieldName();
-
- const TString uniformName = name + "." + fieldName;
+ const TType &fieldType = *fields[i]->type();
+ const TString uniformName = name + "." + fields[i]->name();
declareUniform(fieldType, uniformName, fieldIndex);
fieldIndex += fieldType.totalRegisterCount();
}
diff --git a/src/3rdparty/angle/src/compiler/OutputHLSL.h b/src/3rdparty/angle/src/compiler/OutputHLSL.h
index 749a3461b3..cde4120718 100644
--- a/src/3rdparty/angle/src/compiler/OutputHLSL.h
+++ b/src/3rdparty/angle/src/compiler/OutputHLSL.h
@@ -108,6 +108,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesPointCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
+ bool mUsesFragDepth;
bool mUsesXor;
bool mUsesMod1;
bool mUsesMod2v;
@@ -120,18 +121,6 @@ class OutputHLSL : public TIntermTraverser
bool mUsesFaceforward2;
bool mUsesFaceforward3;
bool mUsesFaceforward4;
- bool mUsesEqualMat2;
- bool mUsesEqualMat3;
- bool mUsesEqualMat4;
- bool mUsesEqualVec2;
- bool mUsesEqualVec3;
- bool mUsesEqualVec4;
- bool mUsesEqualIVec2;
- bool mUsesEqualIVec3;
- bool mUsesEqualIVec4;
- bool mUsesEqualBVec2;
- bool mUsesEqualBVec3;
- bool mUsesEqualBVec4;
bool mUsesAtan2_1;
bool mUsesAtan2_2;
bool mUsesAtan2_3;
diff --git a/src/3rdparty/angle/src/compiler/ParseHelper.cpp b/src/3rdparty/angle/src/compiler/ParseHelper.cpp
index 441ff35e00..1f8538e6a4 100644
--- a/src/3rdparty/angle/src/compiler/ParseHelper.cpp
+++ b/src/3rdparty/angle/src/compiler/ParseHelper.cpp
@@ -22,7 +22,7 @@
// Look at a '.' field selector string and change it into offsets
// for a vector.
//
-bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line)
+bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc& line)
{
fields.num = (int) compString.size();
if (fields.num > 4) {
@@ -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, int line)
+bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, const TSourceLoc& line)
{
fields.wholeRow = false;
fields.wholeCol = false;
@@ -175,22 +175,24 @@ void TParseContext::recover()
//
// Used by flex/bison to output all syntax and parsing errors.
//
-void TParseContext::error(TSourceLoc loc,
+void TParseContext::error(const TSourceLoc& loc,
const char* reason, const char* token,
const char* extraInfo)
{
pp::SourceLocation srcLoc;
- DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
diagnostics.writeInfo(pp::Diagnostics::ERROR,
srcLoc, reason, token, extraInfo);
}
-void TParseContext::warning(TSourceLoc loc,
+void TParseContext::warning(const TSourceLoc& loc,
const char* reason, const char* token,
const char* extraInfo) {
pp::SourceLocation srcLoc;
- DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
diagnostics.writeInfo(pp::Diagnostics::WARNING,
srcLoc, reason, token, extraInfo);
}
@@ -203,7 +205,7 @@ void TParseContext::trace(const char* str)
//
// Same error message for all places assignments don't work.
//
-void TParseContext::assignError(int line, const char* op, TString left, TString right)
+void TParseContext::assignError(const TSourceLoc& line, const char* op, TString left, TString right)
{
std::stringstream extraInfoStream;
extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
@@ -214,7 +216,7 @@ void TParseContext::assignError(int line, const char* op, TString left, TString
//
// Same error message for all places unary operations don't work.
//
-void TParseContext::unaryOpError(int line, const char* op, TString operand)
+void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString operand)
{
std::stringstream extraInfoStream;
extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
@@ -226,7 +228,7 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand)
//
// Same error message for all binary operations don't work.
//
-void TParseContext::binaryOpError(int line, const char* op, TString left, TString right)
+void TParseContext::binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right)
{
std::stringstream extraInfoStream;
extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
@@ -235,7 +237,7 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin
error(line, " wrong operand types ", op, extraInfo.c_str());
}
-bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){
+bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type){
if (!checksPrecisionErrors)
return false;
switch( type ){
@@ -263,7 +265,7 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy
//
// Returns true if the was an error.
//
-bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node)
+bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped* node)
{
TIntermSymbol* symNode = node->getAsSymbolNode();
TIntermBinary* binaryNode = node->getAsBinaryNode();
@@ -317,7 +319,6 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
case EvqAttribute: message = "can't modify an attribute"; break;
case EvqUniform: message = "can't modify a uniform"; break;
case EvqVaryingIn: message = "can't modify a varying"; break;
- case EvqInput: message = "can't modify an input"; break;
case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break;
case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
@@ -409,7 +410,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
//
// Returns true if the was an error.
//
-bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
+bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const char* token)
{
if (global)
return false;
@@ -428,7 +429,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
//
// Returns true if there was an error.
//
-bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
+bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& identifier)
{
static const char* reservedErrMsg = "reserved built-in name";
if (!symbolTable.atBuiltInLevel()) {
@@ -466,7 +467,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
//
// Returns true if there was an error in construction.
//
-bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
+bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
{
*type = function.getReturnType();
@@ -487,7 +488,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
// again, there is an extra argument, so 'overfull' will become true.
//
- int size = 0;
+ size_t size = 0;
bool constType = true;
bool full = false;
bool overFull = false;
@@ -534,7 +535,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
return true;
}
- if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
+ if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
return true;
}
@@ -568,7 +569,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
//
// returns true in case of an error
//
-bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
+bool TParseContext::voidErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& pubType)
{
if (pubType.type == EbtVoid) {
error(line, "illegal use of type 'void'", identifier.c_str());
@@ -582,7 +583,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP
//
// returns true in case of an error
//
-bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
+bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* type)
{
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
error(line, "boolean expression expected", "");
@@ -596,7 +597,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
//
// returns true in case of an error
//
-bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
+bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TPublicType& pType)
{
if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
error(line, "boolean expression expected", "");
@@ -606,7 +607,7 @@ bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
return false;
}
-bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
+bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason)
{
if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) {
@@ -625,7 +626,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
return false;
}
-bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
+bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType)
{
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
pType.type == EbtStruct) {
@@ -640,7 +641,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
return false;
}
-bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
+bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type)
{
if ((qualifier == EvqOut || qualifier == EvqInOut) &&
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
@@ -657,9 +658,9 @@ bool TParseContext::containsSampler(TType& type)
return true;
if (type.getBasicType() == EbtStruct) {
- TTypeList& structure = *type.getStruct();
- for (unsigned int i = 0; i < structure.size(); ++i) {
- if (containsSampler(*structure[i].type))
+ const TFieldList& fields = type.getStruct()->fields();
+ for (unsigned int i = 0; i < fields.size(); ++i) {
+ if (containsSampler(*fields[i]->type()))
return true;
}
}
@@ -672,7 +673,7 @@ bool TParseContext::containsSampler(TType& type)
//
// Returns true if there was an error.
//
-bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
+bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size)
{
TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || constant->getBasicType() != EbtInt) {
@@ -696,7 +697,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
//
// Returns true if there is an error.
//
-bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
+bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type)
{
if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
@@ -711,7 +712,7 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
//
// Returns true if there is an error.
//
-bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
+bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type)
{
//
// Can the type be an array?
@@ -732,7 +733,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
//
// Returns true if there was an error.
//
-bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
+bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable)
{
//
// Don't check for reserved word use until after we know it's not in the symbol table,
@@ -777,16 +778,6 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
return true;
}
- TType* t = variable->getArrayInformationType();
- while (t != 0) {
- if (t->getMaxArraySize() > type.arraySize) {
- error(line, "higher index value already used for the array", identifier.c_str());
- return true;
- }
- t->setArraySize(type.arraySize);
- t = t->getArrayInformationType();
- }
-
if (type.arraySize)
variable->getType().setArraySize(type.arraySize);
}
@@ -797,56 +788,12 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
return false;
}
-bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
-{
- bool builtIn = false;
- TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
- if (symbol == 0) {
- error(line, " undeclared identifier", node->getSymbol().c_str());
- return true;
- }
- TVariable* variable = static_cast<TVariable*>(symbol);
-
- type->setArrayInformationType(variable->getArrayInformationType());
- variable->updateArrayInformationType(type);
-
- // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
- // its an error
- if (node->getSymbol() == "gl_FragData") {
- TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn);
- ASSERT(fragData);
-
- int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
- if (fragDataValue <= size) {
- error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
- return true;
- }
- }
-
- // we dont want to update the maxArraySize when this flag is not set, we just want to include this
- // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
- if (!updateFlag)
- return false;
-
- size++;
- variable->getType().setMaxArraySize(size);
- type->setMaxArraySize(size);
- TType* tt = type;
-
- while(tt->getArrayInformationType() != 0) {
- tt = tt->getArrayInformationType();
- tt->setMaxArraySize(size);
- }
-
- return false;
-}
-
//
// Enforce non-initializer type/qualifier rules.
//
// Returns true if there was an error.
//
-bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array)
+bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array)
{
if (type.qualifier == EvqConst)
{
@@ -878,7 +825,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
//
// Returns true if there was an error.
//
-bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable)
+bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable)
{
if (reservedErrorCheck(line, identifier))
recover();
@@ -898,7 +845,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
return false;
}
-bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
+bool TParseContext::paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
{
if (qualifier != EvqConst && qualifier != EvqTemporary) {
error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
@@ -917,7 +864,7 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
return false;
}
-bool TParseContext::extensionErrorCheck(int line, const TString& extension)
+bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension)
{
const TExtensionBehavior& extBehavior = extensionBehavior();
TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
@@ -945,18 +892,17 @@ bool TParseContext::supportsExtension(const char* extension)
return (iter != extbehavior.end());
}
-void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior)
+bool TParseContext::isExtensionEnabled(const char* extension) const
{
- pp::SourceLocation loc;
- DecodeSourceLoc(line, &loc.file, &loc.line);
- directiveHandler.handleExtension(loc, extName, behavior);
-}
+ const TExtensionBehavior& extbehavior = extensionBehavior();
+ TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
-void TParseContext::handlePragmaDirective(int line, const char* name, const char* value)
-{
- pp::SourceLocation loc;
- DecodeSourceLoc(line, &loc.file, &loc.line);
- directiveHandler.handlePragma(loc, name, value);
+ if (iter == extbehavior.end())
+ {
+ return false;
+ }
+
+ return (iter->second == EBhEnable || iter->second == EBhRequire);
}
/////////////////////////////////////////////////////////////////////////////////
@@ -970,12 +916,13 @@ void TParseContext::handlePragmaDirective(int line, const char* name, const char
//
// Return the function symbol if found, otherwise 0.
//
-const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
+const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, 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);
- if (symbol == 0) {
+ if (symbol == 0 || symbol->isFunction()) {
symbol = symbolTable.find(call->getMangledName(), builtIn);
}
@@ -996,7 +943,7 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu
// Initializers show up in several places in the grammar. Have one set of
// code to handle them here.
//
-bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
+bool TParseContext::executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
{
TType type = TType(pType);
@@ -1048,13 +995,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
return true;
}
if (initializer->getAsConstantUnion()) {
- ConstantUnion* unionArray = variable->getConstPointer();
-
- if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
- *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
- } else {
- variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
- }
+ variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
} else if (initializer->getAsSymbolNode()) {
const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
const TVariable* tVar = static_cast<const TVariable*>(symbol);
@@ -1108,16 +1049,16 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
//
// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
//
-TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
+TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc& line)
{
if (node == 0)
return 0;
TIntermAggregate* aggrNode = node->getAsAggregate();
- TTypeList::const_iterator memberTypes;
+ TFieldList::const_iterator memberFields;
if (op == EOpConstructStruct)
- memberTypes = type->getStruct()->begin();
+ memberFields = type->getStruct()->fields().begin();
TType elementType = *type;
if (type->isArray())
@@ -1139,7 +1080,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, (*memberTypes).type, 1, node->getLine(), false);
+ newNode = constructStruct(node, (*memberFields)->type(), 1, node->getLine(), false);
else
newNode = constructBuiltIn(type, op, node, node->getLine(), false);
@@ -1170,7 +1111,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, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true);
+ newNode = constructStruct(*p, memberFields[paramCount]->type(), paramCount+1, node->getLine(), true);
else
newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
@@ -1216,7 +1157,7 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co
//
// Returns 0 for an error or the constructed node.
//
-TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
+TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, const TSourceLoc& line, bool subset)
{
TIntermTyped* newNode;
TOperator basicOp;
@@ -1278,7 +1219,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T
//
// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
//
-TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset)
+TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, const TSourceLoc& line, bool subset)
{
if (*type == node->getAsTyped()->getType()) {
if (subset)
@@ -1305,7 +1246,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int
// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
// a constant matrix.
//
-TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line)
{
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1327,7 +1268,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
ConstantUnion* constArray = new ConstantUnion[fields.num];
for (int i = 0; i < fields.num; i++) {
- if (fields.offsets[i] >= node->getType().getObjectSize()) {
+ if (fields.offsets[i] >= node->getType().getNominalSize()) {
std::stringstream extraInfoStream;
extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
std::string extraInfo = extraInfoStream.str();
@@ -1349,7 +1290,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
//
-TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line)
{
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1384,7 +1325,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
// to the function could either be a symbol node (a[0] where a is a constant array)that represents a
// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
//
-TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line)
{
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1400,9 +1341,8 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
index = 0;
}
- int arrayElementSize = arrayElementType.getObjectSize();
-
if (tempConstantNode) {
+ size_t arrayElementSize = arrayElementType.getObjectSize();
ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
} else {
@@ -1421,22 +1361,21 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
// 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, TSourceLoc line)
+TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, const TSourceLoc& line)
{
- const TTypeList* fields = node->getType().getStruct();
- TIntermTyped *typedNode;
- int instanceSize = 0;
- unsigned int index = 0;
- TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
-
- for ( index = 0; index < fields->size(); ++index) {
- if ((*fields)[index].type->getFieldName() == identifier) {
+ 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;
} else {
- instanceSize += (*fields)[index].type->getObjectSize();
+ instanceSize += fields[index]->type()->getObjectSize();
}
}
+ TIntermTyped* typedNode = 0;
+ TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
if (tempConstantNode) {
ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
@@ -1451,7 +1390,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
return typedNode;
}
-bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
+bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier)
{
++structNestingLevel;
@@ -1477,24 +1416,26 @@ const int kWebGLMaxStructNesting = 4;
} // namespace
-bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType)
+bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
{
if (!isWebGLBasedSpec(shaderSpec)) {
return false;
}
- if (fieldType.getBasicType() != EbtStruct) {
+ if (field.type()->getBasicType() != EbtStruct) {
return false;
}
// We're already inside a structure definition at this point, so add
// one to the field's struct nesting.
- if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) {
- std::stringstream extraInfoStream;
- extraInfoStream << "Reference of struct type " << fieldType.getTypeName()
- << " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
- std::string extraInfo = extraInfoStream.str();
- error(line, "", "", extraInfo.c_str());
+ if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
+ std::stringstream reasonStream;
+ reasonStream << "Reference of struct type "
+ << field.type()->getStruct()->name().c_str()
+ << " exceeds maximum allowed nesting level of "
+ << kWebGLMaxStructNesting;
+ std::string reason = reasonStream.str();
+ error(line, reason.c_str(), field.name().c_str(), "");
return true;
}
@@ -1502,6 +1443,140 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT
}
//
+// Parse an array index expression
+//
+TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression)
+{
+ TIntermTyped *indexedExpression = NULL;
+
+ if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
+ {
+ if (baseExpression->getAsSymbolNode())
+ {
+ error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str());
+ }
+ else
+ {
+ error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
+ }
+ recover();
+ }
+
+ if (indexExpression->getQualifier() == EvqConst)
+ {
+ int index = indexExpression->getAsConstantUnion()->getIConst(0);
+ if (index < 0)
+ {
+ std::stringstream infoStream;
+ infoStream << index;
+ std::string info = infoStream.str();
+ error(location, "negative index", info.c_str());
+ recover();
+ index = 0;
+ }
+ if (baseExpression->getType().getQualifier() == EvqConst)
+ {
+ if (baseExpression->isArray())
+ {
+ // constant folding for arrays
+ indexedExpression = addConstArrayNode(index, baseExpression, location);
+ }
+ else if (baseExpression->isVector())
+ {
+ // constant folding for vectors
+ TVectorFields fields;
+ fields.num = 1;
+ fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
+ indexedExpression = addConstVectorNode(fields, baseExpression, location);
+ }
+ else if (baseExpression->isMatrix())
+ {
+ // constant folding for matrices
+ indexedExpression = addConstMatrixNode(index, baseExpression, location);
+ }
+ }
+ else
+ {
+ if (baseExpression->isArray())
+ {
+ if (index >= baseExpression->getType().getArraySize())
+ {
+ std::stringstream extraInfoStream;
+ extraInfoStream << "array index out of range '" << index << "'";
+ std::string extraInfo = extraInfoStream.str();
+ error(location, "", "[", extraInfo.c_str());
+ recover();
+ index = baseExpression->getType().getArraySize() - 1;
+ }
+ else if (baseExpression->getQualifier() == EvqFragData && index > 0 && !isExtensionEnabled("GL_EXT_draw_buffers"))
+ {
+ error(location, "", "[", "array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled");
+ recover();
+ index = 0;
+ }
+ }
+ else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
+ {
+ std::stringstream extraInfoStream;
+ extraInfoStream << "field selection out of range '" << index << "'";
+ std::string extraInfo = extraInfoStream.str();
+ error(location, "", "[", extraInfo.c_str());
+ recover();
+ index = baseExpression->getType().getNominalSize() - 1;
+ }
+
+ indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
+ indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
+ }
+ }
+ else
+ {
+ indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
+ }
+
+ if (indexedExpression == 0)
+ {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setFConst(0.0f);
+ indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
+ }
+ else if (baseExpression->isArray())
+ {
+ const TType &baseType = baseExpression->getType();
+ if (baseType.getStruct())
+ {
+ TType copyOfType(baseType.getStruct());
+ indexedExpression->setType(copyOfType);
+ }
+ else
+ {
+ indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->isMatrix()));
+ }
+
+ if (baseExpression->getType().getQualifier() == EvqConst)
+ {
+ indexedExpression->getTypePointer()->setQualifier(EvqConst);
+ }
+ }
+ else if (baseExpression->isMatrix())
+ {
+ TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
+ indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getNominalSize()));
+ }
+ else if (baseExpression->isVector())
+ {
+ TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
+ indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
+ }
+ else
+ {
+ indexedExpression->setType(baseExpression->getType());
+ }
+
+ return indexedExpression;
+}
+
+//
// Parse an array of strings using yyparse.
//
// Returns 0 for success.
diff --git a/src/3rdparty/angle/src/compiler/ParseHelper.h b/src/3rdparty/angle/src/compiler/ParseHelper.h
index 26a3ea1308..c2b3c3f7ec 100644
--- a/src/3rdparty/angle/src/compiler/ParseHelper.h
+++ b/src/3rdparty/angle/src/compiler/ParseHelper.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.
//
@@ -33,10 +33,8 @@ struct TParseContext {
compileOptions(options),
sourcePath(sourcePath),
treeRoot(0),
- lexAfterType(false),
loopNestingLevel(0),
structNestingLevel(0),
- inTypeParen(false),
currentFunctionType(NULL),
functionReturnsValue(false),
checksPrecisionErrors(checksPrecErrors),
@@ -51,16 +49,13 @@ struct TParseContext {
int compileOptions;
const char* sourcePath; // Path of source file or NULL.
TIntermNode* treeRoot; // root of parse tree being created
- bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
int loopNestingLevel; // 0 if outside all loops
int structNestingLevel; // incremented while parsing a struct declaration
- bool inTypeParen; // true if in parentheses, looking only for an identifier
const TType* currentFunctionType; // the return type of the function that's currently being parsed
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.
TString HashErrMsg;
- bool AfterEOF;
TDiagnostics diagnostics;
TDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor;
@@ -68,71 +63,69 @@ struct TParseContext {
int numErrors() const { return diagnostics.numErrors(); }
TInfoSink& infoSink() { return diagnostics.infoSink(); }
- void error(TSourceLoc loc, const char *reason, const char* token,
+ void error(const TSourceLoc& loc, const char *reason, const char* token,
const char* extraInfo="");
- void warning(TSourceLoc loc, const char* reason, const char* token,
+ void warning(const TSourceLoc& loc, const char* reason, const char* token,
const char* extraInfo="");
void trace(const char* str);
void recover();
- bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
- bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
+ bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line);
+ bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, const TSourceLoc& line);
- bool reservedErrorCheck(int line, const TString& identifier);
- void assignError(int line, const char* op, TString left, TString right);
- void unaryOpError(int line, const char* op, TString operand);
- void binaryOpError(int line, const char* op, TString left, TString right);
- bool precisionErrorCheck(int line, TPrecision precision, TBasicType type);
- bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
+ bool reservedErrorCheck(const TSourceLoc& line, const TString& identifier);
+ void assignError(const TSourceLoc& line, const char* op, TString left, TString right);
+ void unaryOpError(const TSourceLoc& line, const char* op, TString operand);
+ void binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right);
+ bool precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type);
+ bool lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped*);
bool constErrorCheck(TIntermTyped* node);
bool integerErrorCheck(TIntermTyped* node, const char* token);
- bool globalErrorCheck(int line, bool global, const char* token);
- bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
- bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
- bool arrayQualifierErrorCheck(int line, TPublicType type);
- bool arrayTypeErrorCheck(int line, TPublicType type);
- bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
- bool voidErrorCheck(int, const TString&, const TPublicType&);
- bool boolErrorCheck(int, const TIntermTyped*);
- bool boolErrorCheck(int, const TPublicType&);
- bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
- bool structQualifierErrorCheck(int line, const TPublicType& pType);
- bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
- bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array);
- bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable);
- bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
- bool extensionErrorCheck(int line, const TString&);
+ bool globalErrorCheck(const TSourceLoc& line, bool global, const char* token);
+ bool constructorErrorCheck(const TSourceLoc& line, TIntermNode*, TFunction&, TOperator, TType*);
+ 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 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 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 paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
+ bool extensionErrorCheck(const TSourceLoc& line, const TString&);
+ const TPragma& pragma() const { return directiveHandler.pragma(); }
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
bool supportsExtension(const char* extension);
- void handleExtensionDirective(int line, const char* extName, const char* behavior);
-
- const TPragma& pragma() const { return directiveHandler.pragma(); }
- void handlePragmaDirective(int line, const char* name, const char* value);
+ bool isExtensionEnabled(const char* extension) const;
bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode);
- const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
- bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
+ const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0);
+ bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
- bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
- TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
+ TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
- TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
- TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
- TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
- TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
- TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
- TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
+ TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&, bool subset);
+ TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, const TSourceLoc&, bool subset);
+ 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* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
// Performs an error check for embedded struct declarations.
// Returns true if an error was raised due to the declaration of
// this struct.
- bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
+ bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
void exitStructDeclaration();
- bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType);
+ bool structNestingErrorCheck(const TSourceLoc& line, const TField& field);
};
int PaParseStrings(size_t count, const char* const string[], const int length[],
diff --git a/src/3rdparty/angle/src/compiler/PoolAlloc.cpp b/src/3rdparty/angle/src/compiler/PoolAlloc.cpp
index 9ef4f59f5c..eb993567b3 100644
--- a/src/3rdparty/angle/src/compiler/PoolAlloc.cpp
+++ b/src/3rdparty/angle/src/compiler/PoolAlloc.cpp
@@ -17,55 +17,32 @@
OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
-void InitializeGlobalPools()
-{
- TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
- if (globalPools)
- return;
-
- TThreadGlobalPools* threadData = new TThreadGlobalPools();
- threadData->globalPoolAllocator = 0;
-
- OS_SetTLSValue(PoolIndex, threadData);
-}
-
-void FreeGlobalPools()
-{
- // Release the allocated memory for this thread.
- TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
- if (!globalPools)
- return;
-
- delete globalPools;
-}
-
bool InitializePoolIndex()
{
- // Allocate a TLS index.
- if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
- return false;
+ assert(PoolIndex == OS_INVALID_TLS_INDEX);
- return true;
+ PoolIndex = OS_AllocTLSIndex();
+ return PoolIndex != OS_INVALID_TLS_INDEX;
}
void FreePoolIndex()
{
- // Release the TLS index.
+ assert(PoolIndex != OS_INVALID_TLS_INDEX);
+
OS_FreeTLSIndex(PoolIndex);
+ PoolIndex = OS_INVALID_TLS_INDEX;
}
-TPoolAllocator& GetGlobalPoolAllocator()
+TPoolAllocator* GetGlobalPoolAllocator()
{
- TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
- return *threadData->globalPoolAllocator;
+ assert(PoolIndex != OS_INVALID_TLS_INDEX);
+ return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
}
void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
{
- TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
- threadData->globalPoolAllocator = poolAllocator;
+ assert(PoolIndex != OS_INVALID_TLS_INDEX);
+ OS_SetTLSValue(PoolIndex, poolAllocator);
}
//
@@ -228,24 +205,27 @@ void TPoolAllocator::popAll()
void* TPoolAllocator::allocate(size_t numBytes)
{
+ //
+ // Just keep some interesting statistics.
+ //
+ ++numCalls;
+ totalBytes += numBytes;
+
// If we are using guard blocks, all allocations are bracketed by
// them: [guardblock][allocation][guardblock]. numBytes is how
// much memory the caller asked for. allocationSize is the total
// size including guard blocks. In release build,
// guardBlockSize=0 and this all gets optimized away.
size_t allocationSize = TAllocation::allocationSize(numBytes);
-
- //
- // Just keep some interesting statistics.
- //
- ++numCalls;
- totalBytes += numBytes;
+ // Detect integer overflow.
+ if (allocationSize < numBytes)
+ return 0;
//
// Do the allocation, most likely case first, for efficiency.
// This step could be moved to be inline sometime.
//
- if (currentPageOffset + allocationSize <= pageSize) {
+ if (allocationSize <= pageSize - currentPageOffset) {
//
// Safe to allocate from currentPageOffset.
//
@@ -256,12 +236,16 @@ void* TPoolAllocator::allocate(size_t numBytes)
return initializeAllocation(inUseList, memory, numBytes);
}
- if (allocationSize + headerSkip > pageSize) {
+ if (allocationSize > pageSize - headerSkip) {
//
// Do a multi-page allocation. Don't mix these with the others.
// The OS is efficient and allocating and free-ing multiple pages.
//
size_t numBytesToAlloc = allocationSize + headerSkip;
+ // Detect integer overflow.
+ if (numBytesToAlloc < allocationSize)
+ return 0;
+
tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
if (memory == 0)
return 0;
diff --git a/src/3rdparty/angle/src/compiler/PoolAlloc.h b/src/3rdparty/angle/src/compiler/PoolAlloc.h
index a8a59c69ac..edd249c4d3 100644
--- a/src/3rdparty/angle/src/compiler/PoolAlloc.h
+++ b/src/3rdparty/angle/src/compiler/PoolAlloc.h
@@ -219,14 +219,8 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
-extern TPoolAllocator& GetGlobalPoolAllocator();
+extern TPoolAllocator* GetGlobalPoolAllocator();
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
-#define GlobalPoolAllocator GetGlobalPoolAllocator()
-
-struct TThreadGlobalPools
-{
- TPoolAllocator* globalPoolAllocator;
-};
//
// This STL compatible allocator is intended to be used as the allocator
@@ -253,7 +247,7 @@ public:
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
- pool_allocator() : allocator(&GlobalPoolAllocator) { }
+ pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
pool_allocator(TPoolAllocator& a) : allocator(&a) { }
pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
diff --git a/src/3rdparty/angle/src/compiler/ShHandle.h b/src/3rdparty/angle/src/compiler/ShHandle.h
index 28049305e0..873580a99c 100644
--- a/src/3rdparty/angle/src/compiler/ShHandle.h
+++ b/src/3rdparty/angle/src/compiler/ShHandle.h
@@ -70,6 +70,7 @@ public:
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; }
@@ -83,15 +84,15 @@ protected:
bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
// Clears the results from the previous compilation.
void clearResults();
- // Return true if function recursion is detected.
- bool detectRecursion(TIntermNode* root);
+ // Return true if function recursion is detected or call depth exceeded.
+ bool detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth);
// 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
// functionality mandated in GLSL 1.0 spec Appendix A.
bool validateLimitations(TIntermNode* root);
- // Collect info for all attribs and uniforms.
- void collectAttribsUniforms(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.
@@ -106,6 +107,8 @@ 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.
+ bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
// Get the resources set by InitBuiltInSymbolTable
@@ -120,6 +123,8 @@ private:
ShShaderSpec shaderSpec;
int maxUniformVectors;
+ int maxExpressionComplexity;
+ int maxCallStackDepth;
ShBuiltInResources compileResources;
@@ -138,6 +143,7 @@ private:
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;
diff --git a/src/3rdparty/angle/src/compiler/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/ShaderLang.cpp
index 92f39311c2..42cd5cc5c1 100644
--- a/src/3rdparty/angle/src/compiler/ShaderLang.cpp
+++ b/src/3rdparty/angle/src/compiler/ShaderLang.cpp
@@ -15,20 +15,25 @@
#include "compiler/preprocessor/length_limits.h"
#include "compiler/ShHandle.h"
#include "compiler/TranslatorHLSL.h"
+#include "compiler/VariablePacker.h"
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
//
-static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
- size_t expectedValue)
+static bool checkVariableMaxLengths(const ShHandle handle,
+ size_t expectedValue)
{
size_t activeUniformLimit = 0;
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
size_t activeAttribLimit = 0;
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
- return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
+ size_t varyingLimit = 0;
+ ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
+ return (expectedValue == activeUniformLimit &&
+ expectedValue == activeAttribLimit &&
+ expectedValue == varyingLimit);
}
static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
@@ -38,62 +43,14 @@ static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue
return (expectedValue == mappedNameMaxLength);
}
-static void getVariableInfo(ShShaderInfo varType,
- const ShHandle handle,
- int index,
- size_t* length,
- int* size,
- ShDataType* type,
- char* name,
- char* mappedName)
-{
- if (!handle || !size || !type || !name)
- return;
- ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
- (varType == SH_ACTIVE_UNIFORMS));
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (compiler == 0)
- return;
-
- const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
- compiler->getAttribs() : compiler->getUniforms();
- if (index < 0 || index >= static_cast<int>(varList.size()))
- return;
-
- const TVariableInfo& varInfo = varList[index];
- if (length) *length = varInfo.name.size();
- *size = varInfo.size;
- *type = varInfo.type;
-
- // This size must match that queried by
- // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
- // in ShGetInfo, below.
- size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
- ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
- strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
- name[activeUniformAndAttribLength - 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;
- ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
- strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
- mappedName[maxMappedNameLength - 1] = 0;
- }
-}
-
//
-// Driver must call this first, once, before doing any other
-// compiler operations.
+// Driver must call this first, once, before doing any other compiler operations.
+// Subsequent calls to this function are no-op.
//
int ShInitialize()
{
- if (!InitProcess())
- return 0;
-
- return 1;
+ static const bool kInitialized = InitProcess();
+ return kInitialized ? 1 : 0;
}
//
@@ -101,9 +58,7 @@ int ShInitialize()
//
int ShFinalize()
{
- if (!DetachProcess())
- return 0;
-
+ DetachProcess();
return 1;
}
@@ -127,6 +82,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->OES_EGL_image_external = 0;
resources->ARB_texture_rectangle = 0;
resources->EXT_draw_buffers = 0;
+ resources->EXT_frag_depth = 0;
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;
@@ -144,9 +100,6 @@ ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
ShShaderOutput output,
const ShBuiltInResources* resources)
{
- if (!InitThread())
- return 0;
-
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
@@ -185,9 +138,6 @@ int ShCompile(
size_t numStrings,
int compileOptions)
{
- if (!InitThread())
- return 0;
-
if (handle == 0)
return 0;
@@ -229,6 +179,12 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
+ case SH_VARYINGS:
+ *params = compiler->getVaryings().size();
+ break;
+ case SH_VARYING_MAX_LENGTH:
+ *params = 1 + MAX_SYMBOL_NAME_LEN;
+ break;
case SH_MAPPED_NAME_MAX_LENGTH:
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
// handle array and struct dereferences.
@@ -286,28 +242,71 @@ void ShGetObjectCode(const ShHandle handle, char* objCode)
strcpy(objCode, infoSink.obj.c_str());
}
-void ShGetActiveAttrib(const ShHandle handle,
+void ShGetVariableInfo(const ShHandle handle,
+ ShShaderInfo varType,
int index,
size_t* length,
int* size,
ShDataType* type,
+ ShPrecisionType* precision,
+ int* staticUse,
char* name,
char* mappedName)
{
- getVariableInfo(SH_ACTIVE_ATTRIBUTES,
- handle, index, length, size, type, name, mappedName);
-}
+ if (!handle || !size || !type || !precision || !staticUse || !name)
+ return;
+ ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
+ (varType == SH_ACTIVE_UNIFORMS) ||
+ (varType == SH_VARYINGS));
-void ShGetActiveUniform(const ShHandle handle,
- int index,
- size_t* length,
- int* size,
- ShDataType* type,
- char* name,
- char* mappedName)
-{
- getVariableInfo(SH_ACTIVE_UNIFORMS,
- handle, index, length, size, type, name, mappedName);
+ TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+ TCompiler* compiler = base->getAsCompiler();
+ if (compiler == 0)
+ return;
+
+ const TVariableInfoList& varList =
+ varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() :
+ (varType == SH_ACTIVE_UNIFORMS ? compiler->getUniforms() :
+ compiler->getVaryings());
+ if (index < 0 || index >= static_cast<int>(varList.size()))
+ return;
+
+ const TVariableInfo& varInfo = varList[index];
+ if (length) *length = varInfo.name.size();
+ *size = varInfo.size;
+ *type = varInfo.type;
+ switch (varInfo.precision) {
+ case EbpLow:
+ *precision = SH_PRECISION_LOWP;
+ break;
+ case EbpMedium:
+ *precision = SH_PRECISION_MEDIUMP;
+ break;
+ case EbpHigh:
+ *precision = SH_PRECISION_HIGHP;
+ break;
+ default:
+ // Some types does not support precision, for example, boolean.
+ *precision = SH_PRECISION_UNDEFINED;
+ break;
+ }
+ *staticUse = varInfo.staticUse ? 1 : 0;
+
+ // 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;
+ 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;
+ ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
+ strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
+ mappedName[maxMappedNameLength - 1] = 0;
+ }
}
void ShGetNameHashingEntry(const ShHandle handle,
@@ -370,3 +369,19 @@ void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
default: UNREACHABLE();
}
}
+
+int ShCheckVariablesWithinPackingLimits(
+ int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
+{
+ if (varInfoArraySize == 0)
+ return 1;
+ ASSERT(varInfoArray);
+ TVariableInfoList variables;
+ for (size_t ii = 0; ii < varInfoArraySize; ++ii)
+ {
+ TVariableInfo var(varInfoArray[ii].type, varInfoArray[ii].size);
+ variables.push_back(var);
+ }
+ VariablePacker packer;
+ return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
+}
diff --git a/src/3rdparty/angle/src/compiler/SymbolTable.cpp b/src/3rdparty/angle/src/compiler/SymbolTable.cpp
index 847c1e4085..a7ce21680f 100644
--- a/src/3rdparty/angle/src/compiler/SymbolTable.cpp
+++ b/src/3rdparty/angle/src/compiler/SymbolTable.cpp
@@ -17,48 +17,34 @@
#include <stdio.h>
#include <algorithm>
-
-#include "common/angleutils.h"
+#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),
- maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
+ 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) {
+ if (p.userDef)
structure = p.userDef->getStruct();
- typeName = NewPoolTString(p.userDef->getTypeName().c_str());
- computeDeepestStructNesting();
- }
}
//
// Recursively generate mangled names.
//
-void TType::buildMangledName(TString& mangledName)
+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 += "struct-";
- if (typeName)
- mangledName += *typeName;
- {// support MSVC++6.0
- for (unsigned int i = 0; i < structure->size(); ++i) {
- mangledName += '-';
- (*structure)[i].type->buildMangledName(mangledName);
- }
- }
- default:
- break;
+ 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());
@@ -69,53 +55,72 @@ void TType::buildMangledName(TString& mangledName)
mangledName += buf;
mangledName += ']';
}
+ return mangledName;
}
-int TType::getStructSize() const
+size_t TType::getObjectSize() const
{
- if (!getStruct()) {
- assert(false && "Not a struct");
- return 0;
- }
+ size_t totalSize = 0;
- if (structureSize == 0)
- for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
- structureSize += ((*tl).type)->getObjectSize();
+ 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 structureSize;
+ return totalSize;
}
-void TType::computeDeepestStructNesting()
+bool TStructure::containsArrays() const
{
- if (!getStruct()) {
- return;
+ for (size_t i = 0; i < mFields->size(); ++i) {
+ const TType* fieldType = (*mFields)[i]->type();
+ if (fieldType->isArray() || fieldType->isStructureContainingArrays())
+ return true;
}
+ return false;
+}
- int maxNesting = 0;
- for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
- maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
+TString TStructure::buildMangledName() const
+{
+ TString mangledName("struct-");
+ mangledName += *mName;
+ for (size_t i = 0; i < mFields->size(); ++i) {
+ mangledName += '-';
+ mangledName += (*mFields)[i]->type()->getMangledName();
}
-
- deepestStructNesting = 1 + maxNesting;
+ return mangledName;
}
-bool TType::isStructureContainingArrays() const
+size_t TStructure::calculateObjectSize() const
{
- if (!structure)
- {
- return false;
+ 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;
+}
- for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
- {
- if (member->type->isArray() ||
- member->type->isStructureContainingArrays())
- {
- return true;
- }
+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 false;
+ return 1 + maxNesting;
}
//
@@ -196,84 +201,16 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
{
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->relateToExtension(ext);
- }
+ TSymbol* symbol = it->second;
+ if (symbol->getName() == name)
+ symbol->relateToExtension(ext);
}
}
-TSymbol::TSymbol(const TSymbol& copyOf)
-{
- name = NewPoolTString(copyOf.name->c_str());
- uniqueId = copyOf.uniqueId;
-}
-
-TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
+TSymbolTable::~TSymbolTable()
{
- type.copyType(copyOf.type, remapper);
- userType = copyOf.userType;
- // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
- assert(copyOf.arrayInformationType == 0);
- arrayInformationType = 0;
-
- if (copyOf.unionArray) {
- assert(!copyOf.type.getStruct());
- assert(copyOf.type.getObjectSize() == 1);
- unionArray = new ConstantUnion[1];
- unionArray[0] = copyOf.unionArray[0];
- } else
- unionArray = 0;
-}
-
-TVariable* TVariable::clone(TStructureMap& remapper)
-{
- TVariable *variable = new TVariable(*this, remapper);
-
- return variable;
-}
-
-TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
-{
- for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
- TParameter param;
- parameters.push_back(param);
- parameters.back().copyParam(copyOf.parameters[i], remapper);
- }
-
- returnType.copyType(copyOf.returnType, remapper);
- mangledName = copyOf.mangledName;
- op = copyOf.op;
- defined = copyOf.defined;
-}
-
-TFunction* TFunction::clone(TStructureMap& remapper)
-{
- TFunction *function = new TFunction(*this, remapper);
-
- return function;
-}
-
-TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
-{
- TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
- tLevel::iterator iter;
- for (iter = level.begin(); iter != level.end(); ++iter) {
- symTableLevel->insert(*iter->second->clone(remapper));
- }
-
- return symTableLevel;
-}
-
-void TSymbolTable::copyTable(const TSymbolTable& copyOf)
-{
- TStructureMap remapper;
- uniqueId = copyOf.uniqueId;
- for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
- table.push_back(copyOf.table[i]->clone(remapper));
- }
- for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
- precisionStack.push_back( copyOf.precisionStack[i] );
- }
+ 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/src/3rdparty/angle/src/compiler/SymbolTable.h b/src/3rdparty/angle/src/compiler/SymbolTable.h
index d27aa332b7..bebad4b92e 100644
--- a/src/3rdparty/angle/src/compiler/SymbolTable.h
+++ b/src/3rdparty/angle/src/compiler/SymbolTable.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.
//
@@ -32,6 +32,7 @@
#include <assert.h>
+#include "common/angleutils.h"
#include "compiler/InfoSink.h"
#include "compiler/intermediate.h"
@@ -40,22 +41,26 @@
//
class TSymbol {
public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- TSymbol(const TString *n) : name(n) { }
+ 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;
- TSymbol(const TSymbol&);
- virtual TSymbol* clone(TStructureMap& remapper) = 0;
+ virtual void dump(TInfoSink &infoSink) const = 0;
+ void relateToExtension(const TString& ext) { extension = ext; }
+ const TString& getExtension() const { return extension; }
-protected:
+private:
+ DISALLOW_COPY_AND_ASSIGN(TSymbol);
+
+ int uniqueId; // For real comparing during code generation
const TString *name;
- unsigned int uniqueId; // For real comparing during code generation
+ TString extension;
};
//
@@ -70,15 +75,13 @@ protected:
//
class TVariable : public TSymbol {
public:
- TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
+ 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); }
- void updateArrayInformationType(TType *t) { arrayInformationType = t; }
- TType* getArrayInformationType() { return arrayInformationType; }
virtual void dump(TInfoSink &infoSink) const;
@@ -100,16 +103,15 @@ public:
delete[] unionArray;
unionArray = constArray;
}
- TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
- virtual TVariable* clone(TStructureMap& remapper);
-protected:
+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;
- TType *arrayInformationType; // this is used for updating maxArraySize in all the references to a given symbol
};
//
@@ -119,11 +121,6 @@ protected:
struct TParameter {
TString *name;
TType* type;
- void copyParam(const TParameter& param, TStructureMap& remapper)
- {
- name = NewPoolTString(param.name->c_str());
- type = param.type->clone(remapper);
- }
};
//
@@ -163,9 +160,6 @@ public:
void relateToOperator(TOperator o) { op = o; }
TOperator getBuiltInOp() const { return op; }
- void relateToExtension(const TString& ext) { extension = ext; }
- const TString& getExtension() const { return extension; }
-
void setDefined() { defined = true; }
bool isDefined() { return defined; }
@@ -173,16 +167,15 @@ public:
const TParameter& getParam(size_t i) const { return parameters[i]; }
virtual void dump(TInfoSink &infoSink) const;
- TFunction(const TFunction&, TStructureMap& remapper);
- virtual TFunction* clone(TStructureMap& remapper);
-protected:
+private:
+ DISALLOW_COPY_AND_ASSIGN(TFunction);
+
typedef TVector<TParameter> TParamList;
TParamList parameters;
TType returnType;
TString mangledName;
TOperator op;
- TString extension;
bool defined;
};
@@ -194,21 +187,24 @@ public:
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TSymbolTableLevel() { }
~TSymbolTableLevel();
- bool insert(TSymbol& symbol)
+ bool insert(const TString &name, TSymbol &symbol)
{
//
// returning true means symbol was added to the table
//
- tInsertResult result;
- result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
+ 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);
@@ -231,7 +227,6 @@ public:
void relateToOperator(const char* name, TOperator op);
void relateToExtension(const char* name, const TString& ext);
void dump(TInfoSink &infoSink) const;
- TSymbolTableLevel* clone(TStructureMap& remapper);
protected:
tLevel level;
@@ -247,13 +242,7 @@ public:
// that the symbol table has not been preloaded with built-ins.
//
}
-
- ~TSymbolTable()
- {
- // level 0 is always built In symbols, so we never pop that out
- while (table.size() > 1)
- pop();
- }
+ ~TSymbolTable();
//
// When the symbol table is initialized with the built-ins, there should
@@ -266,13 +255,15 @@ public:
void push()
{
table.push_back(new TSymbolTableLevel);
- precisionStack.push_back( PrecisionStackLevel() );
+ precisionStack.push_back(new PrecisionStackLevel);
}
void pop()
- {
- delete table[currentLevel()];
- table.pop_back();
+ {
+ delete table.back();
+ table.pop_back();
+
+ delete precisionStack.back();
precisionStack.pop_back();
}
@@ -282,6 +273,35 @@ public:
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();
@@ -298,16 +318,11 @@ public:
return symbol;
}
- TSymbol *findBuiltIn(const TString &name)
+ TSymbol* findBuiltIn(const TString &name)
{
return table[0]->find(name);
}
- TSymbolTableLevel* getGlobalLevel() {
- assert(table.size() >= 2);
- return table[1];
- }
-
TSymbolTableLevel* getOuterLevel() {
assert(table.size() >= 2);
return table[currentLevel() - 1];
@@ -319,32 +334,29 @@ public:
void relateToExtension(const char* name, const TString& ext) {
table[0]->relateToExtension(name, ext);
}
- int getMaxSymbolId() { return uniqueId; }
void dump(TInfoSink &infoSink) const;
- void copyTable(const TSymbolTable& copyOf);
- bool setDefaultPrecision( const TPublicType& type, TPrecision prec ){
- if (IsSampler(type.type))
- return true; // Skip sampler types for the time being
- if (type.type != EbtFloat && type.type != EbtInt)
- return false; // Only set default precision for int/float
+ 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
+ (*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( type != EbtFloat && type != EbtInt ) return EbpUndefined;
+ 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.
+ 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() ){
+ while (level >= 0) {
+ it = precisionStack[level]->find(type);
+ if (it != precisionStack[level]->end()) {
prec = (*it).second;
break;
}
@@ -353,13 +365,18 @@ public:
return prec;
}
-protected:
+private:
int currentLevel() const { return static_cast<int>(table.size()) - 1; }
- std::vector<TSymbolTableLevel*> table;
- typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
- std::vector< PrecisionStackLevel > precisionStack;
+ 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/src/3rdparty/angle/src/compiler/Types.h b/src/3rdparty/angle/src/compiler/Types.h
index 854bb44c07..505fa8e3bf 100644
--- a/src/3rdparty/angle/src/compiler/Types.h
+++ b/src/3rdparty/angle/src/compiler/Types.h
@@ -7,30 +7,85 @@
#ifndef _TYPES_INCLUDED
#define _TYPES_INCLUDED
+#include "common/angleutils.h"
+
#include "compiler/BaseTypes.h"
#include "compiler/Common.h"
#include "compiler/debug.h"
-class TType;
struct TPublicType;
+class TType;
-//
-// Need to have association of line numbers to types in a list for building structs.
-//
-struct TTypeLine {
- TType* type;
- int line;
+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<TTypeLine> TTypeList;
-inline TTypeList* NewPoolTTypeList()
+typedef TVector<TField*> TFieldList;
+inline TFieldList* NewPoolTFieldList()
{
- void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));
- return new(memory) TTypeList;
+ void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
+ return new(memory) TFieldList;
}
-typedef TMap<TTypeList*, TTypeList*> TStructureMap;
-typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
+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.
@@ -38,72 +93,16 @@ typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
class TType
{
public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+ POOL_ALLOCATOR_NEW_DELETE();
TType() {}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
- type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
- maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
+ type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
{
}
explicit TType(const TPublicType &p);
- TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
- maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
- {
- typeName = NewPoolTString(n.c_str());
- }
-
- void copyType(const TType& copyOf, TStructureMap& remapper)
+ TType(TStructure* userDef, TPrecision p = EbpUndefined) :
+ type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
{
- type = copyOf.type;
- precision = copyOf.precision;
- qualifier = copyOf.qualifier;
- size = copyOf.size;
- matrix = copyOf.matrix;
- array = copyOf.array;
- arraySize = copyOf.arraySize;
-
- TStructureMapIterator iter;
- if (copyOf.structure) {
- if ((iter = remapper.find(structure)) == remapper.end()) {
- // create the new structure here
- structure = NewPoolTTypeList();
- for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
- TTypeLine typeLine;
- typeLine.line = (*copyOf.structure)[i].line;
- typeLine.type = (*copyOf.structure)[i].type->clone(remapper);
- structure->push_back(typeLine);
- }
- } else {
- structure = iter->second;
- }
- } else
- structure = 0;
-
- fieldName = 0;
- if (copyOf.fieldName)
- fieldName = NewPoolTString(copyOf.fieldName->c_str());
- typeName = 0;
- if (copyOf.typeName)
- typeName = NewPoolTString(copyOf.typeName->c_str());
-
- mangled = 0;
- if (copyOf.mangled)
- mangled = NewPoolTString(copyOf.mangled->c_str());
-
- structureSize = copyOf.structureSize;
- maxArraySize = copyOf.maxArraySize;
- deepestStructNesting = copyOf.deepestStructNesting;
- assert(copyOf.arrayInformationType == 0);
- arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
- }
-
- TType* clone(TStructureMap& remapper)
- {
- TType *newType = new TType();
- newType->copyType(*this, remapper);
-
- return newType;
}
TBasicType getBasicType() const { return type; }
@@ -119,34 +118,18 @@ public:
int getNominalSize() const { return size; }
void setNominalSize(int s) { size = s; }
// Full size of single instance of type
- int getObjectSize() const
- {
- int totalSize;
-
- if (getBasicType() == EbtStruct)
- totalSize = getStructSize();
- else if (matrix)
- totalSize = size * size;
- else
- totalSize = size;
-
- if (isArray())
- totalSize *= std::max(getArraySize(), getMaxArraySize());
-
- return totalSize;
- }
+ size_t getObjectSize() const;
int elementRegisterCount() const
{
- TTypeList *structure = getStruct();
-
if (structure)
{
+ const TFieldList &fields = getStruct()->fields();
int registerCount = 0;
- for (size_t i = 0; i < structure->size(); i++)
+ for (size_t i = 0; i < fields.size(); i++)
{
- registerCount += (*structure)[i].type->totalRegisterCount();
+ registerCount += fields[i]->type()->totalRegisterCount();
}
return registerCount;
@@ -179,47 +162,20 @@ public:
bool isArray() const { return array ? true : false; }
int getArraySize() const { return arraySize; }
void setArraySize(int s) { array = true; arraySize = s; }
- int getMaxArraySize () const { return maxArraySize; }
- void setMaxArraySize (int s) { maxArraySize = s; }
- void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
- void setArrayInformationType(TType* t) { arrayInformationType = t; }
- TType* getArrayInformationType() const { return arrayInformationType; }
+ void clearArrayness() { array = false; arraySize = 0; }
bool isVector() const { return size > 1 && !matrix; }
bool isScalar() const { return size == 1 && !matrix && !structure; }
- TTypeList* getStruct() const { return structure; }
- void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
-
- const TString& getTypeName() const
- {
- assert(typeName);
- return *typeName;
- }
- void setTypeName(const TString& n)
- {
- typeName = NewPoolTString(n.c_str());
- }
-
- bool isField() const { return fieldName != 0; }
- const TString& getFieldName() const
- {
- assert(fieldName);
- return *fieldName;
- }
- void setFieldName(const TString& n)
- {
- fieldName = NewPoolTString(n.c_str());
- }
+ TStructure* getStruct() const { return structure; }
+ void setStruct(TStructure* s) { structure = s; }
- TString& getMangledName() {
- if (!mangled) {
- mangled = NewPoolTString("");
- buildMangledName(*mangled);
- *mangled += ';' ;
+ const TString& getMangledName() const {
+ if (mangled.empty()) {
+ mangled = buildMangledName();
+ mangled += ';';
}
-
- return *mangled;
+ return mangled;
}
bool sameElementType(const TType& right) const {
@@ -267,14 +223,16 @@ public:
// 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 deepestStructNesting; }
+ int getDeepestStructNesting() const {
+ return structure ? structure->deepestNesting() : 0;
+ }
- bool isStructureContainingArrays() const;
+ bool isStructureContainingArrays() const {
+ return structure ? structure->containsArrays() : false;
+ }
-protected:
- void buildMangledName(TString&);
- int getStructSize() const;
- void computeDeepestStructNesting();
+private:
+ TString buildMangledName() const;
TBasicType type : 6;
TPrecision precision;
@@ -283,16 +241,10 @@ protected:
unsigned int matrix : 1;
unsigned int array : 1;
int arraySize;
- int maxArraySize;
- TType* arrayInformationType;
- TTypeList* structure; // 0 unless this is a struct
- mutable int structureSize;
- int deepestStructNesting;
+ TStructure* structure; // 0 unless this is a struct
- TString *fieldName; // for structure field names
- TString *mangled;
- TString *typeName; // for structure field type name
+ mutable TString mangled;
};
//
@@ -314,9 +266,9 @@ struct TPublicType
bool array;
int arraySize;
TType* userDef;
- int line;
+ TSourceLoc line;
- void setBasic(TBasicType bt, TQualifier q, int ln = 0)
+ void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln)
{
type = bt;
qualifier = q;
diff --git a/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
index a5562d09a4..736ceeaefc 100644
--- a/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
+++ b/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
@@ -435,7 +435,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
return true;
bool valid = true;
- TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
+ TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
TSymbol* symbol = symbolTable.find(node->getName());
ASSERT(symbol && symbol->isFunction());
TFunction* function = static_cast<TFunction*>(symbol);
diff --git a/src/3rdparty/angle/src/compiler/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/VariableInfo.cpp
index eb6bea9b0f..f3f7b1ef35 100644
--- a/src/3rdparty/angle/src/compiler/VariableInfo.cpp
+++ b/src/3rdparty/angle/src/compiler/VariableInfo.cpp
@@ -6,15 +6,17 @@
#include "compiler/VariableInfo.h"
-static TString arrayBrackets(int index)
+namespace {
+
+TString arrayBrackets(int index)
{
TStringStream stream;
stream << "[" << index << "]";
return stream.str();
}
-// Returns the data type for an attribute or uniform.
-static ShDataType getVariableDataType(const TType& type)
+// Returns the data type for an attribute, uniform, or varying.
+ShDataType getVariableDataType(const TType& type)
{
switch (type.getBasicType()) {
case EbtFloat:
@@ -70,22 +72,22 @@ static ShDataType getVariableDataType(const TType& type)
return SH_NONE;
}
-static void getBuiltInVariableInfo(const TType& type,
- const TString& name,
- const TString& mappedName,
- TVariableInfoList& infoList);
-static void getUserDefinedVariableInfo(const TType& type,
- const TString& name,
- const TString& mappedName,
- TVariableInfoList& infoList,
- ShHashFunction64 hashFunction);
-
-// Returns info for an attribute or uniform.
-static void getVariableInfo(const TType& type,
+void getBuiltInVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList,
- ShHashFunction64 hashFunction)
+ TVariableInfoList& infoList);
+void getUserDefinedVariableInfo(const TType& type,
+ const TString& name,
+ const TString& mappedName,
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction);
+
+// Returns info for an attribute, uniform, or varying.
+void getVariableInfo(const TType& type,
+ const TString& name,
+ const TString& mappedName,
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction)
{
if (type.getBasicType() == EbtStruct) {
if (type.isArray()) {
@@ -119,6 +121,7 @@ void getBuiltInVariableInfo(const TType& type,
varInfo.mappedName = mappedName.c_str();
varInfo.size = 1;
}
+ varInfo.precision = type.getPrecision();
varInfo.type = getVariableDataType(type);
infoList.push_back(varInfo);
}
@@ -131,86 +134,156 @@ void getUserDefinedVariableInfo(const TType& type,
{
ASSERT(type.getBasicType() == EbtStruct);
- const TTypeList* structure = type.getStruct();
- for (size_t i = 0; i < structure->size(); ++i) {
- const TType* fieldType = (*structure)[i].type;
- getVariableInfo(*fieldType,
- name + "." + fieldType->getFieldName(),
- mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
+ const TFieldList& 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();
+ getVariableInfo(fieldType,
+ name + "." + fieldName,
+ mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
infoList,
hashFunction);
}
}
+TVariableInfo* findVariable(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList)
+{
+ // TODO(zmo): optimize this function.
+ TString myName = name;
+ if (type.isArray())
+ myName += "[0]";
+ for (size_t ii = 0; ii < infoList.size(); ++ii)
+ {
+ if (infoList[ii].name.c_str() == myName)
+ return &(infoList[ii]);
+ }
+ return NULL;
+}
+
+} // namespace anonymous
+
TVariableInfo::TVariableInfo()
+ : type(SH_NONE),
+ size(0),
+ precision(EbpUndefined),
+ staticUse(false)
{
}
TVariableInfo::TVariableInfo(ShDataType type, int size)
: type(type),
- size(size)
+ size(size),
+ precision(EbpUndefined),
+ staticUse(false)
{
}
-CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
- TVariableInfoList& uniforms,
- ShHashFunction64 hashFunction)
+CollectVariables::CollectVariables(TVariableInfoList& attribs,
+ TVariableInfoList& uniforms,
+ TVariableInfoList& varyings,
+ ShHashFunction64 hashFunction)
: mAttribs(attribs),
mUniforms(uniforms),
+ mVaryings(varyings),
+ mPointCoordAdded(false),
+ mFrontFacingAdded(false),
+ mFragCoordAdded(false),
mHashFunction(hashFunction)
{
}
-// We are only interested in attribute and uniform variable declaration.
-void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
-{
-}
-
-void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
-bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
+// We want to check whether a uniform/varying is statically used
+// because we only count the used ones in packing computing.
+// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
+// toward varying counting if they are statically used in a fragment
+// shader.
+void CollectVariables::visitSymbol(TIntermSymbol* symbol)
{
- return false;
-}
-
-bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
-{
- return false;
-}
-
-bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
-{
- return false;
+ ASSERT(symbol != NULL);
+ TVariableInfo* var = NULL;
+ switch (symbol->getQualifier())
+ {
+ case EvqVaryingOut:
+ case EvqInvariantVaryingOut:
+ case EvqVaryingIn:
+ case EvqInvariantVaryingIn:
+ var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings);
+ break;
+ case EvqUniform:
+ var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms);
+ break;
+ case EvqFragCoord:
+ if (!mFragCoordAdded) {
+ TVariableInfo info;
+ info.name = "gl_FragCoord";
+ info.mappedName = "gl_FragCoord";
+ info.type = SH_FLOAT_VEC4;
+ info.size = 1;
+ info.precision = EbpMedium; // Use mediump as it doesn't really matter.
+ info.staticUse = true;
+ mVaryings.push_back(info);
+ mFragCoordAdded = true;
+ }
+ return;
+ case EvqFrontFacing:
+ if (!mFrontFacingAdded) {
+ TVariableInfo info;
+ info.name = "gl_FrontFacing";
+ info.mappedName = "gl_FrontFacing";
+ info.type = SH_BOOL;
+ info.size = 1;
+ info.precision = EbpUndefined;
+ info.staticUse = true;
+ mVaryings.push_back(info);
+ mFrontFacingAdded = true;
+ }
+ return;
+ case EvqPointCoord:
+ if (!mPointCoordAdded) {
+ TVariableInfo info;
+ info.name = "gl_PointCoord";
+ info.mappedName = "gl_PointCoord";
+ info.type = SH_FLOAT_VEC2;
+ info.size = 1;
+ info.precision = EbpMedium; // Use mediump as it doesn't really matter.
+ info.staticUse = true;
+ mVaryings.push_back(info);
+ mPointCoordAdded = true;
+ }
+ return;
+ default:
+ break;
+ }
+ if (var)
+ var->staticUse = true;
}
-bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
+bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
{
- bool visitChildren = false;
+ bool visitChildren = true;
switch (node->getOp())
{
- case EOpSequence:
- // We need to visit sequence children to get to variable declarations.
- visitChildren = true;
- break;
case EOpDeclaration: {
const TIntermSequence& sequence = node->getSequence();
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
- if (qualifier == EvqAttribute || qualifier == EvqUniform)
+ if (qualifier == EvqAttribute || qualifier == EvqUniform ||
+ qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
+ qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
{
- TVariableInfoList& infoList = qualifier == EvqAttribute ?
- mAttribs : mUniforms;
+ TVariableInfoList& infoList = qualifier == EvqAttribute ? mAttribs :
+ (qualifier == EvqUniform ? mUniforms : mVaryings);
for (TIntermSequence::const_iterator i = sequence.begin();
i != sequence.end(); ++i)
{
const TIntermSymbol* variable = (*i)->getAsSymbolNode();
// The only case in which the sequence will not contain a
// TIntermSymbol node is initialization. It will contain a
- // TInterBinary node in that case. Since attributes and unifroms
- // cannot be initialized in a shader, we must have only
- // TIntermSymbol nodes in the sequence.
+ // TInterBinary node in that case. Since attributes, uniforms,
+ // and varyings cannot be initialized in a shader, we must have
+ // only TIntermSymbol nodes in the sequence.
ASSERT(variable != NULL);
TString processedSymbol;
if (mHashFunction == NULL)
@@ -222,6 +295,7 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
processedSymbol,
infoList,
mHashFunction);
+ visitChildren = false;
}
}
break;
@@ -232,13 +306,3 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
return visitChildren;
}
-bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
-{
- return false;
-}
-
-bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
-{
- return false;
-}
-
diff --git a/src/3rdparty/angle/src/compiler/VariableInfo.h b/src/3rdparty/angle/src/compiler/VariableInfo.h
index 4130a589f5..3c7f2a5f84 100644
--- a/src/3rdparty/angle/src/compiler/VariableInfo.h
+++ b/src/3rdparty/angle/src/compiler/VariableInfo.h
@@ -20,28 +20,30 @@ struct TVariableInfo {
TPersistString mappedName;
ShDataType type;
int size;
+ TPrecision precision;
+ bool staticUse;
};
typedef std::vector<TVariableInfo> TVariableInfoList;
-// Traverses intermediate tree to collect all attributes and uniforms.
-class CollectAttribsUniforms : public TIntermTraverser {
+// Traverses intermediate tree to collect all attributes, uniforms, varyings.
+class CollectVariables : public TIntermTraverser {
public:
- CollectAttribsUniforms(TVariableInfoList& attribs,
- TVariableInfoList& uniforms,
- ShHashFunction64 hashFunction);
+ CollectVariables(TVariableInfoList& attribs,
+ TVariableInfoList& uniforms,
+ TVariableInfoList& varyings,
+ ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol*);
- virtual void visitConstantUnion(TIntermConstantUnion*);
- virtual bool visitBinary(Visit, TIntermBinary*);
- virtual bool visitUnary(Visit, TIntermUnary*);
- virtual bool visitSelection(Visit, TIntermSelection*);
virtual bool visitAggregate(Visit, TIntermAggregate*);
- virtual bool visitLoop(Visit, TIntermLoop*);
- virtual bool visitBranch(Visit, TIntermBranch*);
private:
TVariableInfoList& mAttribs;
TVariableInfoList& mUniforms;
+ TVariableInfoList& mVaryings;
+
+ bool mPointCoordAdded;
+ bool mFrontFacingAdded;
+ bool mFragCoordAdded;
ShHashFunction64 mHashFunction;
};
diff --git a/src/3rdparty/angle/src/compiler/glslang.l b/src/3rdparty/angle/src/compiler/glslang.l
index 140a9aeb2d..60663f9a6b 100644
--- a/src/3rdparty/angle/src/compiler/glslang.l
+++ b/src/3rdparty/angle/src/compiler/glslang.l
@@ -47,20 +47,23 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#pragma warning(disable : 4102)
#endif
-#define YY_USER_ACTION yylval->lex.line = yylineno;
+#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
-%option stack
+%option yylineno reentrant bison-bridge bison-locations
%option extra-type="TParseContext*"
-%x COMMENT FIELDS
D [0-9]
L [a-zA-Z_]
@@ -70,73 +73,60 @@ O [0-7]
%%
-%{
- TParseContext* context = yyextra;
-%}
-
- /* Single-line comments */
-"//"[^\n]* ;
-
- /* Multi-line comments */
-"/*" { yy_push_state(COMMENT, yyscanner); }
-<COMMENT>. |
-<COMMENT>\n ;
-<COMMENT>"*/" { yy_pop_state(yyscanner); }
-
-"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" { context->lexAfterType = true; return(FLOAT_TYPE); }
-"int" { context->lexAfterType = true; return(INT_TYPE); }
-"void" { context->lexAfterType = true; return(VOID_TYPE); }
-"bool" { context->lexAfterType = true; return(BOOL_TYPE); }
-"true" { yylval->lex.b = true; return(BOOLCONSTANT); }
-"false" { yylval->lex.b = false; return(BOOLCONSTANT); }
-
-"discard" { return(DISCARD); }
-"return" { return(RETURN); }
-
-"mat2" { context->lexAfterType = true; return(MATRIX2); }
-"mat3" { context->lexAfterType = true; return(MATRIX3); }
-"mat4" { context->lexAfterType = true; return(MATRIX4); }
-
-"vec2" { context->lexAfterType = true; return (VEC2); }
-"vec3" { context->lexAfterType = true; return (VEC3); }
-"vec4" { context->lexAfterType = true; return (VEC4); }
-"ivec2" { context->lexAfterType = true; return (IVEC2); }
-"ivec3" { context->lexAfterType = true; return (IVEC3); }
-"ivec4" { context->lexAfterType = true; return (IVEC4); }
-"bvec2" { context->lexAfterType = true; return (BVEC2); }
-"bvec3" { context->lexAfterType = true; return (BVEC3); }
-"bvec4" { context->lexAfterType = true; return (BVEC4); }
-
-"sampler2D" { context->lexAfterType = true; return SAMPLER2D; }
-"samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; }
-"samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
-"sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; }
-
-"struct" { context->lexAfterType = true; return(STRUCT); }
+"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); }
@@ -183,13 +173,11 @@ O [0-7]
"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); }
+"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); }
@@ -203,72 +191,64 @@ O [0-7]
return check_type(yyscanner);
}
-0[xX]{H}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
-0{O}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
-0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;}
-{D}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
-
-{D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
-{D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
-"."{D}+({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
-
-"+=" { 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); }
-";" { context->lexAfterType = false; return(SEMICOLON); }
-("{"|"<%") { context->lexAfterType = false; return(LEFT_BRACE); }
-("}"|"%>") { return(RIGHT_BRACE); }
-"," { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
-":" { return(COLON); }
-"=" { context->lexAfterType = false; return(EQUAL); }
-"(" { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
-")" { context->inTypeParen = false; return(RIGHT_PAREN); }
-("["|"<:") { return(LEFT_BRACKET); }
-("]"|":>") { return(RIGHT_BRACKET); }
-"." { BEGIN(FIELDS); 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); }
-
-<FIELDS>{L}({L}|{D})* {
- BEGIN(INITIAL);
- yylval->lex.string = NewPoolTString(yytext);
- return FIELD_SELECTION;
-}
-<FIELDS>[ \t\v\f\r] {}
-
-[ \t\v\n\f\r] { }
-<*><<EOF>> { context->AfterEOF = true; yyterminate(); }
-<*>. { context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
+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; }
%%
@@ -278,7 +258,8 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
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_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner);
+ yyset_column(token.location.file, yyscanner);
+ yyset_lineno(token.location.line, yyscanner);
if (len >= max_size)
YY_FATAL_ERROR("Input buffer overflow");
@@ -292,12 +273,10 @@ int check_type(yyscan_t yyscanner) {
int token = IDENTIFIER;
TSymbol* symbol = yyextra->symbolTable.find(yytext);
- if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
+ if (symbol && symbol->isVariable()) {
TVariable* variable = static_cast<TVariable*>(symbol);
- if (variable->isUserType()) {
- yyextra->lexAfterType = true;
+ if (variable->isUserType())
token = TYPE_NAME;
- }
}
yylval->lex.symbol = symbol;
return token;
@@ -306,22 +285,32 @@ int check_type(yyscan_t yyscanner) {
int reserved_word(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
- yyextra->error(yylineno, "Illegal use of reserved word", yytext, "");
+ yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
yyextra->recover();
return 0;
}
-void yyerror(TParseContext* context, const char* reason) {
- struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
-
- if (context->AfterEOF) {
- context->error(yylineno, reason, "unexpected EOF");
- } else {
- context->error(yylineno, reason, yytext);
- }
+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))
@@ -344,12 +333,13 @@ int glslang_finalize(TParseContext* context) {
int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) {
yyrestart(NULL, context->scanner);
- yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
- context->AfterEOF = false;
+ 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();
diff --git a/src/3rdparty/angle/src/compiler/glslang.y b/src/3rdparty/angle/src/compiler/glslang.y
index 8dbcee32ef..c64f736f41 100644
--- a/src/3rdparty/angle/src/compiler/glslang.y
+++ b/src/3rdparty/angle/src/compiler/glslang.y
@@ -39,7 +39,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
#include "GLSLANG/ShaderLang.h"
#define YYENABLE_NLS 0
-#define YYLTYPE_IS_TRIVIAL 1
#define YYLEX_PARAM context->scanner
%}
@@ -47,10 +46,16 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
%expect 1 /* One shift reduce conflict because of if | else */
%pure-parser
%parse-param {TParseContext* context}
+%locations
+
+%code requires {
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+#define SH_MAX_TOKEN_LENGTH 256 // WebGL spec.
+}
%union {
struct {
- TSourceLoc line;
union {
TString *string;
float f;
@@ -60,7 +65,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TSymbol* symbol;
} lex;
struct {
- TSourceLoc line;
TOperator op;
union {
TIntermNode* intermNode;
@@ -74,23 +78,31 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier;
TFunction* function;
TParameter param;
- TTypeLine typeLine;
- TTypeList* typeList;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;
}
%{
-extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
-extern void yyerror(TParseContext* context, const char* reason);
-
-#define FRAG_VERT_ONLY(S, L) { \
- if (context->shaderType != SH_FRAGMENT_SHADER && \
- context->shaderType != SH_VERTEX_SHADER) { \
- context->error(L, " supported in vertex/fragment shaders only ", S); \
- context->recover(); \
- } \
-}
+extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
+extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (YYID(N)) { \
+ (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).last_file = YYRHSLOC(Rhs, N).last_file; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ } \
+ else { \
+ (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \
+ (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
+ } \
+ } while (0)
#define VERTEX_ONLY(S, L) { \
if (context->shaderType != SH_VERTEX_SHADER) { \
@@ -116,7 +128,6 @@ extern void yyerror(TParseContext* context, const char* reason);
%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT
%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT 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
@@ -127,6 +138,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
+%type <lex> identifier
%type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression
@@ -154,8 +166,8 @@ extern void yyerror(TParseContext* context, const char* reason);
%type <interm.type> type_qualifier fully_specified_type type_specifier
%type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier
-%type <interm.typeLine> struct_declarator
-%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
+%type <interm.field> struct_declarator
+%type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
@@ -164,13 +176,17 @@ extern void yyerror(TParseContext* context, const char* reason);
%start translation_unit
%%
+identifier
+ : IDENTIFIER
+ | TYPE_NAME
+
variable_identifier
: IDENTIFIER {
// The symbol table search was done in the lexical phase
const TSymbol* symbol = $1.symbol;
const TVariable* variable;
if (symbol == 0) {
- context->error($1.line, "undeclared identifier", $1.string->c_str());
+ context->error(@1, "undeclared identifier", $1.string->c_str());
context->recover();
TType type(EbtFloat, EbpUndefined);
TVariable* fakeVariable = new TVariable($1.string, type);
@@ -179,10 +195,17 @@ variable_identifier
} else {
// This identifier can only be a variable type symbol
if (! symbol->isVariable()) {
- context->error($1.line, "variable expected", $1.string->c_str());
+ context->error(@1, "variable expected", $1.string->c_str());
context->recover();
}
+
variable = static_cast<const TVariable*>(symbol);
+
+ if (context->symbolTable.findBuiltIn(variable->getName()) &&
+ !variable->getExtension().empty() &&
+ context->extensionErrorCheck(@1, variable->getExtension())) {
+ context->recover();
+ }
}
// don't delete $1.string, it's used by error recovery, and the pool
@@ -191,11 +214,12 @@ variable_identifier
if (variable->getType().getQualifier() == EvqConst ) {
ConstantUnion* constArray = variable->getConstPointer();
TType t(variable->getType());
- $$ = context->intermediate.addConstantUnion(constArray, t, $1.line);
+ $$ = context->intermediate.addConstantUnion(constArray, t, @1);
} else
$$ = context->intermediate.addSymbol(variable->getUniqueId(),
- variable->getName(),
- variable->getType(), $1.line);
+ variable->getName(),
+ variable->getType(),
+ @1);
}
;
@@ -204,27 +228,19 @@ primary_expression
$$ = $1;
}
| INTCONSTANT {
- //
- // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
- // check for overflow for constants
- //
- if (abs($1.i) >= (1 << 16)) {
- context->error($1.line, " integer constant overflow", "");
- context->recover();
- }
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst($1.i);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1);
}
| FLOATCONSTANT {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst($1.f);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
}
| BOOLCONSTANT {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst($1.b);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1);
}
| LEFT_PAREN expression RIGHT_PAREN {
$$ = $2;
@@ -236,103 +252,27 @@ postfix_expression
$$ = $1;
}
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
- if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
- if ($1->getAsSymbolNode())
- context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str());
- else
- context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression");
- context->recover();
- }
- if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
- if ($1->isArray()) { // constant folding for arrays
- $$ = context->addConstArrayNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
- } else if ($1->isVector()) { // constant folding for vectors
- TVectorFields fields;
- fields.num = 1;
- fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
- $$ = context->addConstVectorNode(fields, $1, $2.line);
- } else if ($1->isMatrix()) { // constant folding for matrices
- $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
- }
- } else {
- if ($3->getQualifier() == EvqConst) {
- if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getIConst(0) && !$1->isArray() ) {
- std::stringstream extraInfoStream;
- extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
- std::string extraInfo = extraInfoStream.str();
- context->error($2.line, "", "[", extraInfo.c_str());
- context->recover();
- } else {
- if ($1->isArray()) {
- if ($1->getType().getArraySize() == 0) {
- if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getIConst(0)) {
- if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, $2.line))
- context->recover();
- } else {
- if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
- context->recover();
- }
- } else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) {
- std::stringstream extraInfoStream;
- extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
- std::string extraInfo = extraInfoStream.str();
- context->error($2.line, "", "[", extraInfo.c_str());
- context->recover();
- }
- }
- $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
- }
- } else {
- if ($1->isArray() && $1->getType().getArraySize() == 0) {
- context->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
- context->recover();
- }
-
- $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
- }
- }
- if ($$ == 0) {
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setFConst(0.0f);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
- } else if ($1->isArray()) {
- if ($1->getType().getStruct())
- $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
- else
- $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
-
- if ($1->getType().getQualifier() == EvqConst)
- $$->getTypePointer()->setQualifier(EvqConst);
- } else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
- $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, $1->getNominalSize()));
- else if ($1->isMatrix())
- $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize()));
- else if ($1->isVector() && $1->getType().getQualifier() == EvqConst)
- $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst));
- else if ($1->isVector())
- $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary));
- else
- $$->setType($1->getType());
+ $$ = context->addIndexExpression($1, @2, $3);
}
| function_call {
$$ = $1;
}
- | postfix_expression DOT FIELD_SELECTION {
+ | postfix_expression DOT identifier {
if ($1->isArray()) {
- context->error($3.line, "cannot apply dot operator to an array", ".");
+ 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.line)) {
+ 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.line);
+ $$ = context->addConstVectorNode(fields, $1, @3);
if ($$ == 0) {
context->recover();
$$ = $1;
@@ -341,13 +281,13 @@ postfix_expression
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size()));
} else {
TString vectorString = *$3.string;
- TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line);
- $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
+ 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.line)) {
+ if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, @3)) {
fields.wholeRow = false;
fields.wholeCol = false;
fields.row = 0;
@@ -356,84 +296,78 @@ postfix_expression
}
if (fields.wholeRow || fields.wholeCol) {
- context->error($2.line, " non-scalar fields not implemented yet", ".");
+ 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.line);
- $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+ 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.line);
- $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+ 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 TTypeList* fields = $1->getType().getStruct();
- if (fields == 0) {
- context->error($2.line, "structure has no fields", "Internal Error");
- context->recover();
- $$ = $1;
- } else {
- unsigned int i;
- for (i = 0; i < fields->size(); ++i) {
- if ((*fields)[i].type->getFieldName() == *$3.string) {
- fieldFound = true;
- break;
- }
+ 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.line);
- 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.line);
- $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
- $$->setType(*(*fields)[i].type);
+ }
+ 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 {
- context->error($2.line, " no such field in structure", $3.string->c_str());
- context->recover();
- $$ = $1;
+ 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.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
+ 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
}
| postfix_expression INC_OP {
- if (context->lValueErrorCheck($2.line, "++", $1))
+ if (context->lValueErrorCheck(@2, "++", $1))
context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable);
+ $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable);
if ($$ == 0) {
- context->unaryOpError($2.line, "++", $1->getCompleteString());
+ context->unaryOpError(@2, "++", $1->getCompleteString());
context->recover();
$$ = $1;
}
}
| postfix_expression DEC_OP {
- if (context->lValueErrorCheck($2.line, "--", $1))
+ if (context->lValueErrorCheck(@2, "--", $1))
context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable);
+ $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable);
if ($$ == 0) {
- context->unaryOpError($2.line, "--", $1->getCompleteString());
+ context->unaryOpError(@2, "--", $1->getCompleteString());
context->recover();
$$ = $1;
}
@@ -461,18 +395,18 @@ function_call
// Their parameters will be verified algorithmically.
//
TType type(EbtVoid, EbpUndefined); // use this to get the type back
- if (context->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
+ if (context->constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &type)) {
$$ = 0;
} else {
//
// It's a constructor, of type 'type'.
//
- $$ = context->addConstructor($1.intermNode, &type, op, fnCall, $1.line);
+ $$ = context->addConstructor($1.intermNode, &type, op, fnCall, @1);
}
if ($$ == 0) {
context->recover();
- $$ = context->intermediate.setAggregateOperator(0, op, $1.line);
+ $$ = context->intermediate.setAggregateOperator(0, op, @1);
}
$$->setType(type);
} else {
@@ -481,13 +415,13 @@ function_call
//
const TFunction* fnCandidate;
bool builtIn;
- fnCandidate = context->findFunction($1.line, fnCall, &builtIn);
+ fnCandidate = context->findFunction(@1, fnCall, &builtIn);
if (fnCandidate) {
//
// A declared function.
//
if (builtIn && !fnCandidate->getExtension().empty() &&
- context->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
+ context->extensionErrorCheck(@1, fnCandidate->getExtension())) {
context->recover();
}
op = fnCandidate->getBuiltInOp();
@@ -499,7 +433,7 @@ function_call
//
// Treat it like a built-in unary operator.
//
- $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable);
+ $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1, context->symbolTable);
if ($$ == 0) {
std::stringstream extraInfoStream;
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
@@ -508,12 +442,12 @@ function_call
YYERROR;
}
} else {
- $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
+ $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
}
} else {
// This is a real function call
- $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
+ $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
$$->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user defined function
@@ -540,7 +474,7 @@ function_call
// Put on a dummy node for error recovery
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
context->recover();
}
}
@@ -553,7 +487,7 @@ function_call_or_method
$$ = $1;
}
| postfix_expression DOT function_call_generic {
- context->error($3.line, "methods are not supported", "");
+ context->error(@3, "methods are not supported", "");
context->recover();
$$ = $3;
}
@@ -562,11 +496,9 @@ function_call_or_method
function_call_generic
: function_call_header_with_parameters RIGHT_PAREN {
$$ = $1;
- $$.line = $2.line;
}
| function_call_header_no_parameters RIGHT_PAREN {
$$ = $1;
- $$.line = $2.line;
}
;
@@ -592,7 +524,7 @@ function_call_header_with_parameters
TParameter param = { 0, new TType($3->getType()) };
$1.function->addParameter(param);
$$.function = $1.function;
- $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, $2.line);
+ $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, @2);
}
;
@@ -617,39 +549,39 @@ function_identifier
case EbtFloat:
if ($1.matrix) {
switch($1.size) {
- case 2: op = EOpConstructMat2; break;
- case 3: op = EOpConstructMat3; break;
- case 4: op = EOpConstructMat4; break;
+ 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;
+ 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: FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break;
- case 3: FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break;
- case 4: FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break;
+ 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: FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break;
- case 3: FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break;
- case 4: FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
+ 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.line, "cannot construct this type", getBasicString($1.type));
+ context->error(@1, "cannot construct this type", getBasicString($1.type));
context->recover();
$1.type = EbtFloat;
op = EOpConstructFloat;
@@ -661,14 +593,7 @@ function_identifier
$$ = function;
}
| IDENTIFIER {
- if (context->reservedErrorCheck($1.line, *$1.string))
- context->recover();
- TType type(EbtVoid, EbpUndefined);
- TFunction *function = new TFunction($1.string, type);
- $$ = function;
- }
- | FIELD_SELECTION {
- if (context->reservedErrorCheck($1.line, *$1.string))
+ if (context->reservedErrorCheck(@1, *$1.string))
context->recover();
TType type(EbtVoid, EbpUndefined);
TFunction *function = new TFunction($1.string, type);
@@ -681,28 +606,28 @@ unary_expression
$$ = $1;
}
| INC_OP unary_expression {
- if (context->lValueErrorCheck($1.line, "++", $2))
+ if (context->lValueErrorCheck(@1, "++", $2))
context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable);
+ $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable);
if ($$ == 0) {
- context->unaryOpError($1.line, "++", $2->getCompleteString());
+ context->unaryOpError(@1, "++", $2->getCompleteString());
context->recover();
$$ = $2;
}
}
| DEC_OP unary_expression {
- if (context->lValueErrorCheck($1.line, "--", $2))
+ if (context->lValueErrorCheck(@1, "--", $2))
context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable);
+ $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable);
if ($$ == 0) {
- context->unaryOpError($1.line, "--", $2->getCompleteString());
+ context->unaryOpError(@1, "--", $2->getCompleteString());
context->recover();
$$ = $2;
}
}
| unary_operator unary_expression {
if ($1.op != EOpNull) {
- $$ = context->intermediate.addUnaryMath($1.op, $2, $1.line, context->symbolTable);
+ $$ = context->intermediate.addUnaryMath($1.op, $2, @1, context->symbolTable);
if ($$ == 0) {
const char* errorOp = "";
switch($1.op) {
@@ -710,7 +635,7 @@ unary_expression
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
- context->unaryOpError($1.line, errorOp, $2->getCompleteString());
+ context->unaryOpError(@1, errorOp, $2->getCompleteString());
context->recover();
$$ = $2;
}
@@ -721,28 +646,26 @@ unary_expression
// Grammar Note: No traditional style type casts.
unary_operator
- : PLUS { $$.line = $1.line; $$.op = EOpNull; }
- | DASH { $$.line = $1.line; $$.op = EOpNegative; }
- | BANG { $$.line = $1.line; $$.op = EOpLogicalNot; }
+ : PLUS { $$.op = EOpNull; }
+ | DASH { $$.op = EOpNegative; }
+ | BANG { $$.op = EOpLogicalNot; }
;
// Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
multiplicative_expression
: unary_expression { $$ = $1; }
| multiplicative_expression STAR unary_expression {
- FRAG_VERT_ONLY("*", $2.line);
- $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $1;
}
}
| multiplicative_expression SLASH unary_expression {
- FRAG_VERT_ONLY("/", $2.line);
- $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $1;
}
@@ -752,17 +675,17 @@ multiplicative_expression
additive_expression
: multiplicative_expression { $$ = $1; }
| additive_expression PLUS multiplicative_expression {
- $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $1;
}
}
| additive_expression DASH multiplicative_expression {
- $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $1;
}
@@ -776,43 +699,43 @@ shift_expression
relational_expression
: shift_expression { $$ = $1; }
| relational_expression LEFT_ANGLE shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
| relational_expression RIGHT_ANGLE shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
| relational_expression LE_OP shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
| relational_expression GE_OP shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
;
@@ -820,23 +743,23 @@ relational_expression
equality_expression
: relational_expression { $$ = $1; }
| equality_expression EQ_OP relational_expression {
- $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
| equality_expression NE_OP relational_expression {
- $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
;
@@ -856,13 +779,13 @@ 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.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
;
@@ -870,13 +793,13 @@ 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.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
;
@@ -884,13 +807,13 @@ 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.line, context->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context->symbolTable);
if ($$ == 0) {
- context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString());
context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
}
}
;
@@ -898,15 +821,15 @@ logical_or_expression
conditional_expression
: logical_or_expression { $$ = $1; }
| logical_or_expression QUESTION expression COLON assignment_expression {
- if (context->boolErrorCheck($2.line, $1))
+ if (context->boolErrorCheck(@2, $1))
context->recover();
- $$ = context->intermediate.addSelection($1, $3, $5, $2.line);
+ $$ = context->intermediate.addSelection($1, $3, $5, @2);
if ($3->getType() != $5->getType())
$$ = 0;
if ($$ == 0) {
- context->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
+ context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString());
context->recover();
$$ = $5;
}
@@ -916,11 +839,11 @@ conditional_expression
assignment_expression
: conditional_expression { $$ = $1; }
| unary_expression assignment_operator assignment_expression {
- if (context->lValueErrorCheck($2.line, "assign", $1))
+ if (context->lValueErrorCheck(@2, "assign", $1))
context->recover();
- $$ = context->intermediate.addAssign($2.op, $1, $3, $2.line);
+ $$ = context->intermediate.addAssign($2.op, $1, $3, @2);
if ($$ == 0) {
- context->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
+ context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $1;
}
@@ -928,11 +851,11 @@ assignment_expression
;
assignment_operator
- : EQUAL { $$.line = $1.line; $$.op = EOpAssign; }
- | MUL_ASSIGN { FRAG_VERT_ONLY("*=", $1.line); $$.line = $1.line; $$.op = EOpMulAssign; }
- | DIV_ASSIGN { FRAG_VERT_ONLY("/=", $1.line); $$.line = $1.line; $$.op = EOpDivAssign; }
- | ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; }
- | SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; }
+ : EQUAL { $$.op = EOpAssign; }
+ | MUL_ASSIGN { $$.op = EOpMulAssign; }
+ | DIV_ASSIGN { $$.op = EOpDivAssign; }
+ | ADD_ASSIGN { $$.op = EOpAddAssign; }
+ | SUB_ASSIGN { $$.op = EOpSubAssign; }
;
expression
@@ -940,9 +863,9 @@ expression
$$ = $1;
}
| expression COMMA assignment_expression {
- $$ = context->intermediate.addComma($1, $3, $2.line);
+ $$ = context->intermediate.addComma($1, $3, @2);
if ($$ == 0) {
- context->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
+ context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $3;
}
@@ -970,13 +893,13 @@ declaration
const TParameter &param = function.getParam(i);
if (param.name != 0)
{
- TVariable *variable = new TVariable(param.name, *param.type);
+ TVariable variable(param.name, *param.type);
- prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line);
+ prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
}
else
{
- prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+ prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
}
}
@@ -992,11 +915,11 @@ declaration
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
- context->error($1.line, "precision is not supported in fragment shader", "highp");
+ context->error(@1, "precision is not supported in fragment shader", "highp");
context->recover();
}
if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
- context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type));
+ context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type));
context->recover();
}
$$ = 0;
@@ -1016,24 +939,41 @@ function_prototype
TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
if (prevDec) {
if (prevDec->getReturnType() != $1->getReturnType()) {
- context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
+ context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
context->recover();
}
for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
- context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
+ context->error(@2, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
context->recover();
}
}
}
//
+ // Check for previously declared variables using the same name.
+ //
+ TSymbol *prevSym = context->symbolTable.find($1->getName());
+ if (prevSym)
+ {
+ if (!prevSym->isFunction())
+ {
+ context->error(@2, "redefinition", $1->getName().c_str(), "function");
+ context->recover();
+ }
+ }
+ else
+ {
+ // Insert the unmangled name to detect potential future redefinition as a variable.
+ context->symbolTable.getOuterLevel()->insert($1->getName(), *$1);
+ }
+
+ //
// If this is a redeclaration, it could also be a definition,
// in which case, we want to use the variable names from this one, and not the one that's
// being redeclared. So, pass back up this declaration, not the one in the symbol table.
//
$$.function = $1;
- $$.line = $2.line;
// We're at the inner scope level of the function's arguments and body statement.
// Add the function prototype to the surrounding scope instead.
@@ -1069,7 +1009,7 @@ function_header_with_parameters
//
// This parameter > first is void
//
- context->error($2.line, "cannot be an argument type except for '(void)'", "void");
+ context->error(@2, "cannot be an argument type except for '(void)'", "void");
context->recover();
delete $3.param.type;
} else {
@@ -1083,11 +1023,11 @@ function_header_with_parameters
function_header
: fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
- context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
+ context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
context->recover();
}
// make sure a sampler is not involved as well...
- if (context->structQualifierErrorCheck($2.line, $1))
+ if (context->structQualifierErrorCheck(@2, $1))
context->recover();
// Add the function as a prototype after parsing it (we do not support recursion)
@@ -1102,33 +1042,31 @@ function_header
parameter_declarator
// Type + name
- : type_specifier IDENTIFIER {
+ : type_specifier identifier {
if ($1.type == EbtVoid) {
- context->error($2.line, "illegal use of type 'void'", $2.string->c_str());
+ context->error(@2, "illegal use of type 'void'", $2.string->c_str());
context->recover();
}
- if (context->reservedErrorCheck($2.line, *$2.string))
+ if (context->reservedErrorCheck(@2, *$2.string))
context->recover();
TParameter param = {$2.string, new TType($1)};
- $$.line = $2.line;
$$.param = param;
}
- | type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+ | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
// Check that we can make an array out of this type
- if (context->arrayTypeErrorCheck($3.line, $1))
+ if (context->arrayTypeErrorCheck(@3, $1))
context->recover();
- if (context->reservedErrorCheck($2.line, *$2.string))
+ if (context->reservedErrorCheck(@2, *$2.string))
context->recover();
int size;
- if (context->arraySizeErrorCheck($3.line, $4, size))
+ if (context->arraySizeErrorCheck(@3, $4, size))
context->recover();
$1.setArray(true, size);
TType* type = new TType($1);
TParameter param = { $2.string, type };
- $$.line = $2.line;
$$.param = param;
}
;
@@ -1144,14 +1082,14 @@ parameter_declaration
//
: type_qualifier parameter_qualifier parameter_declarator {
$$ = $3;
- if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+ if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
context->recover();
}
| parameter_qualifier parameter_declarator {
$$ = $2;
- if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+ if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
context->recover();
- if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+ if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
context->recover();
}
//
@@ -1159,14 +1097,14 @@ parameter_declaration
//
| type_qualifier parameter_qualifier parameter_type_specifier {
$$ = $3;
- if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+ if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
context->recover();
}
| parameter_qualifier parameter_type_specifier {
$$ = $2;
- if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+ if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
context->recover();
- if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+ if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
context->recover();
}
;
@@ -1197,83 +1135,83 @@ init_declarator_list
: single_declaration {
$$ = $1;
}
- | init_declarator_list COMMA IDENTIFIER {
+ | init_declarator_list COMMA identifier {
if ($1.type.type == EbtInvariant && !$3.symbol)
{
- context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str());
+ 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.line);
- $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line);
+ TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3);
+ $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3);
- if (context->structQualifierErrorCheck($3.line, $$.type))
+ if (context->structQualifierErrorCheck(@3, $$.type))
context->recover();
- if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type, false))
+ if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false))
context->recover();
TVariable* variable = 0;
- if (context->nonInitErrorCheck($3.line, *$3.string, $$.type, variable))
+ if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable))
context->recover();
if (symbol && variable)
symbol->setId(variable->getUniqueId());
}
- | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
- if (context->structQualifierErrorCheck($3.line, $1.type))
+ | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
+ if (context->structQualifierErrorCheck(@3, $1.type))
context->recover();
- if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true))
+ if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
context->recover();
$$ = $1;
- if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
+ if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type))
context->recover();
else {
$1.type.setArray(true);
TVariable* variable;
- if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+ if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
context->recover();
}
}
- | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- if (context->structQualifierErrorCheck($3.line, $1.type))
+ | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+ if (context->structQualifierErrorCheck(@3, $1.type))
context->recover();
- if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true))
+ if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
context->recover();
$$ = $1;
- if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
+ if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type))
context->recover();
else {
int size;
- if (context->arraySizeErrorCheck($4.line, $5, size))
+ if (context->arraySizeErrorCheck(@4, $5, size))
context->recover();
$1.type.setArray(true, size);
TVariable* variable = 0;
- if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+ 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.line), $3.line);
+ $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, @3), @3);
}
}
- | init_declarator_list COMMA IDENTIFIER EQUAL initializer {
- if (context->structQualifierErrorCheck($3.line, $1.type))
+ | init_declarator_list COMMA identifier EQUAL initializer {
+ if (context->structQualifierErrorCheck(@3, $1.type))
context->recover();
$$ = $1;
TIntermNode* intermNode;
- if (!context->executeInitializer($3.line, *$3.string, $1.type, $5, 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.line);
+ $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4);
else
$$.intermAggregate = $1.intermAggregate;
} else {
@@ -1286,79 +1224,79 @@ init_declarator_list
single_declaration
: fully_specified_type {
$$.type = $1;
- $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), @1), @1);
}
- | fully_specified_type IDENTIFIER {
- TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
- $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+ | 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.line, $$.type))
+ if (context->structQualifierErrorCheck(@2, $$.type))
context->recover();
- if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type, false))
+ if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false))
context->recover();
$$.type = $1;
TVariable* variable = 0;
- if (context->nonInitErrorCheck($2.line, *$2.string, $$.type, variable))
+ if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable))
context->recover();
if (variable && symbol)
symbol->setId(variable->getUniqueId());
}
- | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
- context->error($2.line, "unsized array declarations not supported", $2.string->c_str());
+ | 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.line);
- $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+ TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2);
+ $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
$$.type = $1;
}
- | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+ | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
TType type = TType($1);
int size;
- if (context->arraySizeErrorCheck($2.line, $4, size))
+ if (context->arraySizeErrorCheck(@2, $4, size))
context->recover();
type.setArraySize(size);
- TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, $2.line);
- $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+ TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2);
+ $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
- if (context->structQualifierErrorCheck($2.line, $1))
+ if (context->structQualifierErrorCheck(@2, $1))
context->recover();
- if (context->nonInitConstErrorCheck($2.line, *$2.string, $1, true))
+ if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true))
context->recover();
$$.type = $1;
- if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
+ if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1))
context->recover();
else {
int size;
- if (context->arraySizeErrorCheck($3.line, $4, size))
+ if (context->arraySizeErrorCheck(@3, $4, size))
context->recover();
$1.setArray(true, size);
TVariable* variable = 0;
- if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
+ if (context->arrayErrorCheck(@3, *$2.string, $1, variable))
context->recover();
if (variable && symbol)
symbol->setId(variable->getUniqueId());
}
}
- | fully_specified_type IDENTIFIER EQUAL initializer {
- if (context->structQualifierErrorCheck($2.line, $1))
+ | fully_specified_type identifier EQUAL initializer {
+ if (context->structQualifierErrorCheck(@2, $1))
context->recover();
$$.type = $1;
TIntermNode* intermNode;
- if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
+ if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) {
//
// Build intermediate representation
//
if(intermNode)
- $$.intermAggregate = context->intermediate.makeAggregate(intermNode, $3.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3);
else
$$.intermAggregate = 0;
} else {
@@ -1367,118 +1305,50 @@ single_declaration
}
}
| INVARIANT IDENTIFIER {
- VERTEX_ONLY("invariant declaration", $1.line);
- if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+ VERTEX_ONLY("invariant declaration", @1);
+ if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover();
- $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line);
+ $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
if (!$2.symbol)
{
- context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str());
+ context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str());
context->recover();
$$.intermAggregate = 0;
}
else
{
- TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), $2.line);
- $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+ TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
+ $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
}
}
-
-//
-// Place holder for the pack/unpack languages.
-//
-// | buffer_specifier {
-// $$.intermAggregate = 0;
-// }
;
-// Grammar Note: No 'enum', or 'typedef'.
-
-//
-// Place holder for the pack/unpack languages.
-//
-//%type <interm> buffer_declaration
-//%type <interm.type> buffer_specifier input_or_output buffer_declaration_list
-//buffer_specifier
-// : input_or_output LEFT_BRACE buffer_declaration_list RIGHT_BRACE {
-// }
-// ;
-//
-//input_or_output
-// : INPUT {
-// if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "input"))
-// context->recover();
-// UNPACK_ONLY("input", $1.line);
-// $$.qualifier = EvqInput;
-// }
-// | OUTPUT {
-// if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "output"))
-// context->recover();
-// PACK_ONLY("output", $1.line);
-// $$.qualifier = EvqOutput;
-// }
-// ;
-
-//
-// Place holder for the pack/unpack languages.
-//
-//buffer_declaration_list
-// : buffer_declaration {
-// }
-// | buffer_declaration_list buffer_declaration {
-// }
-// ;
-
-//
-// Input/output semantics:
-// float must be 16 or 32 bits
-// float alignment restrictions?
-// check for only one input and only one output
-// sum of bitfields has to be multiple of 32
-//
-
-//
-// Place holder for the pack/unpack languages.
-//
-//buffer_declaration
-// : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
-// if (context->reservedErrorCheck($2.line, *$2.string, context))
-// context->recover();
-// $$.variable = new TVariable($2.string, $1);
-// if (! context->symbolTable.insert(*$$.variable)) {
-// context->error($2.line, "redefinition", $$.variable->getName().c_str());
-// context->recover();
-// // don't have to delete $$.variable, the pool pop will take care of it
-// }
-// }
-// ;
-
fully_specified_type
: type_specifier {
$$ = $1;
if ($1.array) {
- context->error($1.line, "not supported", "first-class array");
+ context->error(@1, "not supported", "first-class array");
context->recover();
$1.setArray(false);
}
}
| type_qualifier type_specifier {
if ($2.array) {
- context->error($2.line, "not supported", "first-class array");
+ context->error(@2, "not supported", "first-class array");
context->recover();
$2.setArray(false);
}
if ($1.qualifier == EvqAttribute &&
($2.type == EbtBool || $2.type == EbtInt)) {
- context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier));
+ 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.line, "cannot be bool or int", getQualifierString($1.qualifier));
+ context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier));
context->recover();
}
$$ = $2;
@@ -1488,34 +1358,34 @@ fully_specified_type
type_qualifier
: CONST_QUAL {
- $$.setBasic(EbtVoid, EvqConst, $1.line);
+ $$.setBasic(EbtVoid, EvqConst, @1);
}
| ATTRIBUTE {
- VERTEX_ONLY("attribute", $1.line);
- if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute"))
+ VERTEX_ONLY("attribute", @1);
+ if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute"))
context->recover();
- $$.setBasic(EbtVoid, EvqAttribute, $1.line);
+ $$.setBasic(EbtVoid, EvqAttribute, @1);
}
| VARYING {
- if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying"))
+ if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
context->recover();
if (context->shaderType == SH_VERTEX_SHADER)
- $$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
+ $$.setBasic(EbtVoid, EvqVaryingOut, @1);
else
- $$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
+ $$.setBasic(EbtVoid, EvqVaryingIn, @1);
}
| INVARIANT VARYING {
- if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+ if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover();
if (context->shaderType == SH_VERTEX_SHADER)
- $$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line);
+ $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
else
- $$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
+ $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
}
| UNIFORM {
- if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform"))
+ if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
context->recover();
- $$.setBasic(EbtVoid, EvqUniform, $1.line);
+ $$.setBasic(EbtVoid, EvqUniform, @1);
}
;
@@ -1525,7 +1395,7 @@ type_specifier
if ($$.precision == EbpUndefined) {
$$.precision = context->symbolTable.getDefaultPrecision($1.type);
- if (context->precisionErrorCheck($1.line, $$.precision, $1.type)) {
+ if (context->precisionErrorCheck(@1, $$.precision, $1.type)) {
context->recover();
}
}
@@ -1555,11 +1425,11 @@ type_specifier_no_prec
| type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1;
- if (context->arrayTypeErrorCheck($2.line, $1))
+ if (context->arrayTypeErrorCheck(@2, $1))
context->recover();
else {
int size;
- if (context->arraySizeErrorCheck($2.line, $3, size))
+ if (context->arraySizeErrorCheck(@2, $3, size))
context->recover();
$$.setArray(true, size);
}
@@ -1569,118 +1439,105 @@ type_specifier_no_prec
type_specifier_nonarray
: VOID_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtVoid, qual, $1.line);
+ $$.setBasic(EbtVoid, qual, @1);
}
| FLOAT_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
}
| INT_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtInt, qual, $1.line);
+ $$.setBasic(EbtInt, qual, @1);
}
| BOOL_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtBool, qual, $1.line);
+ $$.setBasic(EbtBool, qual, @1);
}
-// | UNSIGNED INT_TYPE {
-// PACK_UNPACK_ONLY("unsigned", $1.line);
-// TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-// $$.setBasic(EbtInt, qual, $1.line);
-// }
| VEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(2);
}
| VEC3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(3);
}
| VEC4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(4);
}
| BVEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtBool, qual, $1.line);
+ $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(2);
}
| BVEC3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtBool, qual, $1.line);
+ $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(3);
}
| BVEC4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtBool, qual, $1.line);
+ $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(4);
}
| IVEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtInt, qual, $1.line);
+ $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(2);
}
| IVEC3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtInt, qual, $1.line);
+ $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(3);
}
| IVEC4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtInt, qual, $1.line);
+ $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(4);
}
| MATRIX2 {
- FRAG_VERT_ONLY("mat2", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(2, true);
}
| MATRIX3 {
- FRAG_VERT_ONLY("mat3", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(3, true);
}
| MATRIX4 {
- FRAG_VERT_ONLY("mat4", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtFloat, qual, $1.line);
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(4, true);
}
| SAMPLER2D {
- FRAG_VERT_ONLY("sampler2D", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtSampler2D, qual, $1.line);
+ $$.setBasic(EbtSampler2D, qual, @1);
}
| SAMPLERCUBE {
- FRAG_VERT_ONLY("samplerCube", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtSamplerCube, qual, $1.line);
+ $$.setBasic(EbtSamplerCube, qual, @1);
}
| SAMPLER_EXTERNAL_OES {
if (!context->supportsExtension("GL_OES_EGL_image_external")) {
- context->error($1.line, "unsupported type", "samplerExternalOES");
+ context->error(@1, "unsupported type", "samplerExternalOES");
context->recover();
}
- FRAG_VERT_ONLY("samplerExternalOES", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtSamplerExternalOES, qual, $1.line);
+ $$.setBasic(EbtSamplerExternalOES, qual, @1);
}
| SAMPLER2DRECT {
if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
- context->error($1.line, "unsupported type", "sampler2DRect");
+ context->error(@1, "unsupported type", "sampler2DRect");
context->recover();
}
- FRAG_VERT_ONLY("sampler2DRect", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtSampler2DRect, qual, $1.line);
+ $$.setBasic(EbtSampler2DRect, qual, @1);
}
| struct_specifier {
- FRAG_VERT_ONLY("struct", $1.line);
$$ = $1;
$$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
}
@@ -1691,29 +1548,29 @@ type_specifier_nonarray
//
TType& structure = static_cast<TVariable*>($1.symbol)->getType();
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- $$.setBasic(EbtStruct, qual, $1.line);
+ $$.setBasic(EbtStruct, qual, @1);
$$.userDef = &structure;
}
;
struct_specifier
- : STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
- if (context->reservedErrorCheck($2.line, *$2.string))
+ : 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($5, *$2.string);
+ 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.line, "redefinition", $2.string->c_str(), "struct");
+ context->error(@2, "redefinition", $2.string->c_str(), "struct");
context->recover();
}
- $$.setBasic(EbtStruct, EvqTemporary, $1.line);
+ $$.setBasic(EbtStruct, EvqTemporary, @1);
$$.userDef = structure;
context->exitStructDeclaration();
}
- | STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
- TType* structure = new TType($4, TString(""));
- $$.setBasic(EbtStruct, EvqTemporary, $1.line);
+ | 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();
}
@@ -1725,14 +1582,15 @@ struct_declaration_list
}
| struct_declaration_list struct_declaration {
$$ = $1;
- for (unsigned int i = 0; i < $2->size(); ++i) {
- for (unsigned int j = 0; j < $$->size(); ++j) {
- if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
- context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
+ for (size_t i = 0; i < $2->size(); ++i) {
+ TField* field = (*$2)[i];
+ for (size_t j = 0; j < $$->size(); ++j) {
+ if ((*$$)[j]->name() == field->name()) {
+ context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
context->recover();
}
}
- $$->push_back((*$2)[i]);
+ $$->push_back(field);
}
}
;
@@ -1741,14 +1599,14 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON {
$$ = $2;
- if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
+ 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;
+ TType* type = (*$$)[i]->type();
type->setBasicType($1.type);
type->setNominalSize($1.size);
type->setMatrix($1.matrix);
@@ -1756,26 +1614,23 @@ struct_declaration
// don't allow arrays of arrays
if (type->isArray()) {
- if (context->arrayTypeErrorCheck($1.line, $1))
+ if (context->arrayTypeErrorCheck(@1, $1))
context->recover();
}
if ($1.array)
type->setArraySize($1.arraySize);
- if ($1.userDef) {
+ if ($1.userDef)
type->setStruct($1.userDef->getStruct());
- type->setTypeName($1.userDef->getTypeName());
- }
- if (context->structNestingErrorCheck($1.line, *type)) {
+ if (context->structNestingErrorCheck(@1, *(*$$)[i]))
context->recover();
- }
}
}
;
struct_declarator_list
: struct_declarator {
- $$ = NewPoolTTypeList();
+ $$ = NewPoolTFieldList();
$$->push_back($1);
}
| struct_declarator_list COMMA struct_declarator {
@@ -1784,26 +1639,24 @@ struct_declarator_list
;
struct_declarator
- : IDENTIFIER {
- if (context->reservedErrorCheck($1.line, *$1.string))
+ : identifier {
+ if (context->reservedErrorCheck(@1, *$1.string))
context->recover();
- $$.type = new TType(EbtVoid, EbpUndefined);
- $$.line = $1.line;
- $$.type->setFieldName(*$1.string);
+ TType* type = new TType(EbtVoid, EbpUndefined);
+ $$ = new TField(type, $1.string);
}
- | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- if (context->reservedErrorCheck($1.line, *$1.string))
+ | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+ if (context->reservedErrorCheck(@1, *$1.string))
context->recover();
- $$.type = new TType(EbtVoid, EbpUndefined);
- $$.line = $1.line;
- $$.type->setFieldName(*$1.string);
-
- int size;
- if (context->arraySizeErrorCheck($2.line, $3, size))
+ TType* type = new TType(EbtVoid, EbpUndefined);
+ int size = 0;
+ if (context->arraySizeErrorCheck(@3, $3, size))
context->recover();
- $$.type->setArraySize(size);
+ type->setArraySize(size);
+
+ $$ = new TField(type, $1.string);
}
;
@@ -1835,7 +1688,7 @@ compound_statement
| LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0) {
$3->setOp(EOpSequence);
- $3->setEndLine($5.line);
+ $3->setLine(@$);
}
$$ = $3;
}
@@ -1859,7 +1712,7 @@ compound_statement_no_new_scope
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2) {
$2->setOp(EOpSequence);
- $2->setEndLine($3.line);
+ $2->setLine(@$);
}
$$ = $2;
}
@@ -1867,10 +1720,10 @@ compound_statement_no_new_scope
statement_list
: statement {
- $$ = context->intermediate.makeAggregate($1, 0);
+ $$ = context->intermediate.makeAggregate($1, @$);
}
| statement_list statement {
- $$ = context->intermediate.growAggregate($1, $2, 0);
+ $$ = context->intermediate.growAggregate($1, $2, @$);
}
;
@@ -1881,9 +1734,9 @@ expression_statement
selection_statement
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
- if (context->boolErrorCheck($1.line, $3))
+ if (context->boolErrorCheck(@1, $3))
context->recover();
- $$ = context->intermediate.addSelection($3, $5, $1.line);
+ $$ = context->intermediate.addSelection($3, $5, @1);
}
;
@@ -1907,14 +1760,14 @@ condition
if (context->boolErrorCheck($1->getLine(), $1))
context->recover();
}
- | fully_specified_type IDENTIFIER EQUAL initializer {
+ | fully_specified_type identifier EQUAL initializer {
TIntermNode* intermNode;
- if (context->structQualifierErrorCheck($2.line, $1))
+ if (context->structQualifierErrorCheck(@2, $1))
context->recover();
- if (context->boolErrorCheck($2.line, $1))
+ if (context->boolErrorCheck(@2, $1))
context->recover();
- if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
+ if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode))
$$ = $4;
else {
context->recover();
@@ -1926,19 +1779,19 @@ condition
iteration_statement
: WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
context->symbolTable.pop();
- $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
+ $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
--context->loopNestingLevel;
}
| DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
- if (context->boolErrorCheck($8.line, $6))
+ if (context->boolErrorCheck(@8, $6))
context->recover();
- $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line);
+ $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
--context->loopNestingLevel;
}
| FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
context->symbolTable.pop();
- $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, $1.line);
+ $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
--context->loopNestingLevel;
}
;
@@ -1975,39 +1828,39 @@ for_rest_statement
jump_statement
: CONTINUE SEMICOLON {
if (context->loopNestingLevel <= 0) {
- context->error($1.line, "continue statement only allowed in loops", "");
+ context->error(@1, "continue statement only allowed in loops", "");
context->recover();
}
- $$ = context->intermediate.addBranch(EOpContinue, $1.line);
+ $$ = context->intermediate.addBranch(EOpContinue, @1);
}
| BREAK SEMICOLON {
if (context->loopNestingLevel <= 0) {
- context->error($1.line, "break statement only allowed in loops", "");
+ context->error(@1, "break statement only allowed in loops", "");
context->recover();
}
- $$ = context->intermediate.addBranch(EOpBreak, $1.line);
+ $$ = context->intermediate.addBranch(EOpBreak, @1);
}
| RETURN SEMICOLON {
- $$ = context->intermediate.addBranch(EOpReturn, $1.line);
+ $$ = context->intermediate.addBranch(EOpReturn, @1);
if (context->currentFunctionType->getBasicType() != EbtVoid) {
- context->error($1.line, "non-void function must return a value", "return");
+ context->error(@1, "non-void function must return a value", "return");
context->recover();
}
}
| RETURN expression SEMICOLON {
- $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line);
+ $$ = context->intermediate.addBranch(EOpReturn, $2, @1);
context->functionReturnsValue = true;
if (context->currentFunctionType->getBasicType() == EbtVoid) {
- context->error($1.line, "void function cannot return a value", "return");
+ context->error(@1, "void function cannot return a value", "return");
context->recover();
} else if (*(context->currentFunctionType) != $2->getType()) {
- context->error($1.line, "function return is not matching type:", "return");
+ context->error(@1, "function return is not matching type:", "return");
context->recover();
}
}
| DISCARD SEMICOLON {
- FRAG_ONLY("discard", $1.line);
- $$ = context->intermediate.addBranch(EOpKill, $1.line);
+ FRAG_ONLY("discard", @1);
+ $$ = context->intermediate.addBranch(EOpKill, @1);
}
;
@@ -2019,7 +1872,7 @@ translation_unit
context->treeRoot = $$;
}
| translation_unit external_declaration {
- $$ = context->intermediate.growAggregate($1, $2, 0);
+ $$ = context->intermediate.growAggregate($1, $2, @$);
context->treeRoot = $$;
}
;
@@ -2041,7 +1894,7 @@ function_definition
if (builtIn)
{
- context->error($1.line, "built-in functions cannot be redefined", function->getName().c_str());
+ context->error(@1, "built-in functions cannot be redefined", function->getName().c_str());
context->recover();
}
@@ -2055,7 +1908,7 @@ function_definition
//
// Then this function already has a body.
//
- context->error($1.line, "function already has a body", function->getName().c_str());
+ context->error(@1, "function already has a body", function->getName().c_str());
context->recover();
}
prevDec->setDefined();
@@ -2065,11 +1918,11 @@ function_definition
//
if (function->getName() == "main") {
if (function->getParamCount() > 0) {
- context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str());
+ context->error(@1, "function cannot take any parameter(s)", function->getName().c_str());
context->recover();
}
if (function->getReturnType().getBasicType() != EbtVoid) {
- context->error($1.line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
+ context->error(@1, "", function->getReturnType().getBasicString(), "main function cannot return a value");
context->recover();
}
}
@@ -2097,7 +1950,7 @@ function_definition
// Insert the parameters with name in the symbol table.
//
if (! context->symbolTable.insert(*variable)) {
- context->error($1.line, "redefinition", variable->getName().c_str());
+ context->error(@1, "redefinition", variable->getName().c_str());
context->recover();
delete variable;
}
@@ -2108,14 +1961,15 @@ function_definition
paramNodes = context->intermediate.growAggregate(
paramNodes,
context->intermediate.addSymbol(variable->getUniqueId(),
- variable->getName(),
- variable->getType(), $1.line),
- $1.line);
+ variable->getName(),
+ variable->getType(),
+ @1),
+ @1);
} else {
- paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+ paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
}
}
- context->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
+ context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1);
$1.intermAggregate = paramNodes;
context->loopNestingLevel = 0;
}
@@ -2123,12 +1977,12 @@ function_definition
//?? Check that all paths return a value if return type != void ?
// May be best done as post process phase on intermediate code
if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
- context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
+ context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
context->recover();
}
- $$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0);
- context->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
+ $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
+ context->intermediate.setAggregateOperator($$, EOpFunction, @1);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
$$->getAsAggregate()->setType($1.function->getReturnType());
@@ -2137,9 +1991,6 @@ function_definition
$$->getAsAggregate()->setOptimize(context->pragma().optimize);
$$->getAsAggregate()->setDebug(context->pragma().debug);
- if ($3 && $3->getAsAggregate())
- $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
-
context->symbolTable.pop();
}
;
diff --git a/src/3rdparty/angle/src/compiler/intermOut.cpp b/src/3rdparty/angle/src/compiler/intermOut.cpp
index f48a049c63..13aa96af6d 100644
--- a/src/3rdparty/angle/src/compiler/intermOut.cpp
+++ b/src/3rdparty/angle/src/compiler/intermOut.cpp
@@ -189,7 +189,9 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
case EOpAny: out << "any"; break;
case EOpAll: out << "all"; break;
- default: out.message(EPrefixError, "Bad unary op");
+ default:
+ out.prefix(EPrefixError);
+ out << "Bad unary op";
}
out << " (" << node->getCompleteString() << ")";
@@ -204,7 +206,8 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
TInfoSinkBase& out = sink;
if (node->getOp() == EOpNull) {
- out.message(EPrefixError, "node is still EOpNull!");
+ out.prefix(EPrefixError);
+ out << "node is still EOpNull!";
return true;
}
@@ -263,7 +266,9 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
case EOpDeclaration: out << "Declaration: "; break;
- default: out.message(EPrefixError, "Bad aggregation op");
+ default:
+ out.prefix(EPrefixError);
+ out << "Bad aggregation op";
}
if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
@@ -311,9 +316,9 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
{
TInfoSinkBase& out = sink;
- int size = node->getType().getObjectSize();
+ size_t size = node->getType().getObjectSize();
- for (int i = 0; i < size; i++) {
+ for (size_t i = 0; i < size; i++) {
OutputTreeText(out, node, depth);
switch (node->getUnionArrayPointer()[i].getType()) {
case EbtBool:
@@ -334,7 +339,7 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
out << " (const int)\n";
break;
default:
- out.message(EPrefixInternalError, "Unknown constant", node->getLine());
+ out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
break;
}
}
diff --git a/src/3rdparty/angle/src/compiler/intermediate.h b/src/3rdparty/angle/src/compiler/intermediate.h
index 8e76ef921f..738621fe70 100644
--- a/src/3rdparty/angle/src/compiler/intermediate.h
+++ b/src/3rdparty/angle/src/compiler/intermediate.h
@@ -18,6 +18,7 @@
#include "GLSLANG/ShaderLang.h"
+#include <algorithm>
#include "compiler/Common.h"
#include "compiler/Types.h"
#include "compiler/ConstantUnion.h"
@@ -204,12 +205,17 @@ class TInfoSink;
//
class TIntermNode {
public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
- TIntermNode() : line(0) {}
+ POOL_ALLOCATOR_NEW_DELETE();
+ TIntermNode() {
+ // TODO: Move this to TSourceLoc constructor
+ // after getting rid of TPublicType.
+ line.first_file = line.last_file = 0;
+ line.first_line = line.last_line = 0;
+ }
+ virtual ~TIntermNode() { }
- TSourceLoc getLine() const { return line; }
- void setLine(TSourceLoc l) { line = l; }
+ const TSourceLoc& getLine() const { return line; }
+ void setLine(const TSourceLoc& l) { line = l; }
virtual void traverse(TIntermTraverser*) = 0;
virtual TIntermTyped* getAsTyped() { return 0; }
@@ -220,7 +226,6 @@ public:
virtual TIntermSelection* getAsSelectionNode() { return 0; }
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual TIntermLoop* getAsLoopNode() { return 0; }
- virtual ~TIntermNode() { }
protected:
TSourceLoc line;
@@ -454,7 +459,7 @@ typedef TVector<int> TQualifierList;
//
class TIntermAggregate : public TIntermOperator {
public:
- TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
+ TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), useEmulatedFunction(false) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
~TIntermAggregate() { }
@@ -474,9 +479,6 @@ public:
void setDebug(bool d) { debug = d; }
bool getDebug() { return debug; }
- void setEndLine(TSourceLoc line) { endLine = line; }
- TSourceLoc getEndLine() const { return endLine; }
-
void setUseEmulatedFunction() { useEmulatedFunction = true; }
bool getUseEmulatedFunction() { return useEmulatedFunction; }
@@ -489,7 +491,6 @@ protected:
bool optimize;
bool debug;
- TSourceLoc endLine;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
@@ -538,14 +539,14 @@ enum Visit
class TIntermTraverser
{
public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
+ POOL_ALLOCATOR_NEW_DELETE();
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
preVisit(preVisit),
inVisit(inVisit),
postVisit(postVisit),
rightToLeft(rightToLeft),
- depth(0) {}
+ depth(0),
+ maxDepth(0) {}
virtual ~TIntermTraverser() {};
virtual void visitSymbol(TIntermSymbol*) {}
@@ -557,7 +558,8 @@ public:
virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
- void incrementDepth() {depth++;}
+ int getMaxDepth() const {return maxDepth;}
+ void incrementDepth() {depth++; maxDepth = std::max(maxDepth, depth); }
void decrementDepth() {depth--;}
// Return the original name if hash function pointer is NULL;
@@ -571,6 +573,7 @@ public:
protected:
int depth;
+ int maxDepth;
};
#endif // __INTERMEDIATE_H
diff --git a/src/3rdparty/angle/src/compiler/localintermediate.h b/src/3rdparty/angle/src/compiler/localintermediate.h
index 56890bd569..1214d821eb 100644
--- a/src/3rdparty/angle/src/compiler/localintermediate.h
+++ b/src/3rdparty/angle/src/compiler/localintermediate.h
@@ -22,37 +22,36 @@ struct TVectorFields {
class TInfoSink;
class TIntermediate {
public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
+ POOL_ALLOCATOR_NEW_DELETE();
TIntermediate(TInfoSink& i) : infoSink(i) { }
- TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
+
+ TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
- TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, TSymbolTable&);
- TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
- TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
- TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc, TSymbolTable&);
- TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
- TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc);
- TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, TSourceLoc);
- TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
- TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
- TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
- TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc);
+ TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&, TSymbolTable&);
+ 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&);
+ TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
+ TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
+ TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&);
+ TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
+ TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
+ TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+ TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
- bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);
- TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc);
- TIntermBranch* addBranch(TOperator, TSourceLoc);
- TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
- TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
+ bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, 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*);
-
-protected:
- TInfoSink& infoSink;
private:
void operator=(TIntermediate&); // prevent assignments
+
+ TInfoSink& infoSink;
};
#endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/src/3rdparty/angle/src/compiler/parseConst.cpp b/src/3rdparty/angle/src/compiler/parseConst.cpp
index 421d31f586..1cc5db8d77 100644
--- a/src/3rdparty/angle/src/compiler/parseConst.cpp
+++ b/src/3rdparty/angle/src/compiler/parseConst.cpp
@@ -38,16 +38,16 @@ protected:
bool visitLoop(Visit visit, TIntermLoop*);
bool visitBranch(Visit visit, TIntermBranch*);
- int index;
+ size_t index;
ConstantUnion *unionArray;
TType type;
TOperator constructorType;
bool singleConstantParam;
TInfoSink& infoSink;
TSymbolTable& symbolTable;
- int size; // size of the constructor ( 4 for vec4)
+ size_t size; // size of the constructor ( 4 for vec4)
bool isMatrix;
- int matrixSize; // dimension of the matrix (nominal size and not the instance size)
+ size_t matrixSize; // dimension of the matrix (nominal size and not the instance size)
};
//
@@ -61,7 +61,7 @@ protected:
void TConstTraverser::visitSymbol(TIntermSymbol* node)
{
- infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Symbol Node found in constant constructor");
return;
}
@@ -74,12 +74,12 @@ bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
TString buf;
buf.append("'constructor' : assigning non-constant to ");
buf.append(type.getCompleteString());
- infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+ infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
error = true;
return false;
}
- infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Binary Node found in constant constructor");
return false;
}
@@ -89,7 +89,7 @@ bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
TString buf;
buf.append("'constructor' : assigning non-constant to ");
buf.append(type.getCompleteString());
- infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+ infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
error = true;
return false;
}
@@ -100,7 +100,7 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
TString buf;
buf.append("'constructor' : assigning non-constant to ");
buf.append(type.getCompleteString());
- infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+ infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
error = true;
return false;
}
@@ -144,7 +144,7 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
{
- infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Selection Node found in constant constructor");
error = true;
return false;
}
@@ -159,16 +159,16 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
}
ConstantUnion* leftUnionArray = unionArray;
- int instanceSize = type.getObjectSize();
+ size_t instanceSize = type.getObjectSize();
if (index >= instanceSize)
return;
if (!singleConstantParam) {
- int size = node->getType().getObjectSize();
+ size_t size = node->getType().getObjectSize();
ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
- for (int i=0; i < size; i++) {
+ for (size_t i = 0; i < size; i++) {
if (index >= instanceSize)
return;
leftUnionArray[index] = rightUnionArray[i];
@@ -176,11 +176,11 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
(index)++;
}
} else {
- int totalSize = index + size;
+ size_t totalSize = index + size;
ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
if (!isMatrix) {
- int count = 0;
- for (int i = index; i < totalSize; i++) {
+ size_t count = 0;
+ for (size_t i = index; i < totalSize; i++) {
if (i >= instanceSize)
return;
@@ -192,9 +192,9 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
count++;
}
} else { // for matrix constructors
- int count = 0;
- int element = index;
- for (int i = index; i < totalSize; i++) {
+ 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 )
@@ -213,14 +213,14 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
{
- infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Loop Node found in constant constructor");
error = true;
return false;
}
bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
{
- infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
+ infoSink.info.message(EPrefixInternalError, node->getLine(), "Branch Node found in constant constructor");
error = true;
return false;
}
@@ -230,7 +230,7 @@ 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(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, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
{
if (root == 0)
return false;
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp
index 5ffc6420bc..b615c85dce 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp
@@ -81,6 +81,11 @@ 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)
{
bool validToken = false;
@@ -95,34 +100,6 @@ void Preprocessor::lex(Token* token)
case Token::PP_HASH:
assert(false);
break;
- case Token::CONST_INT:
- {
- int val = 0;
- if (!token->iValue(&val))
- {
- // Do not mark the token as invalid.
- // Just emit the diagnostic and reset value to 0.
- mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
- token->location, token->text);
- token->text.assign("0");
- }
- validToken = true;
- break;
- }
- case Token::CONST_FLOAT:
- {
- float val = 0;
- if (!token->fValue(&val))
- {
- // Do not mark the token as invalid.
- // Just emit the diagnostic and reset value to 0.0.
- mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
- token->location, token->text);
- token->text.assign("0.0");
- }
- validToken = true;
- break;
- }
case Token::PP_NUMBER:
mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
token->location, token->text);
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
index 7b70180fc8..9a90d79a1a 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
@@ -37,6 +37,12 @@ class Preprocessor
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 lex(Token* token);
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
index 7a6fa87b04..9d131f865a 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
@@ -32,13 +32,13 @@ class Tokenizer : public Lexer
bool leadingSpace;
bool lineStart;
};
- static const std::size_t kMaxTokenLength;
Tokenizer(Diagnostics* diagnostics);
~Tokenizer();
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);
@@ -51,6 +51,7 @@ class Tokenizer : public Lexer
void* mHandle; // Scanner handle.
Context mContext; // Scanner extra.
+ size_t mMaxTokenLength;
};
} // namespace pp
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
index fc81d84f37..01f0177b6c 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
@@ -267,11 +267,9 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
namespace pp {
-// TODO(alokp): Maximum token length should ideally be specified by
-// the preprocessor client, i.e., the compiler.
-const size_t Tokenizer::kMaxTokenLength = 256;
-
-Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
+Tokenizer::Tokenizer(Diagnostics* diagnostics)
+ : mHandle(0),
+ mMaxTokenLength(256)
{
mContext.diagnostics = diagnostics;
}
@@ -304,11 +302,11 @@ void Tokenizer::setLineNumber(int line)
void Tokenizer::lex(Token* token)
{
token->type = yylex(&token->text, &token->location, mHandle);
- if (token->text.size() > kMaxTokenLength)
+ if (token->text.size() > mMaxTokenLength)
{
mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
token->location, token->text);
- token->text.erase(kMaxTokenLength);
+ token->text.erase(mMaxTokenLength);
}
token->flags = 0;
diff --git a/src/3rdparty/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp b/src/3rdparty/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp
index 524c6cf53a..355eb62d65 100644
--- a/src/3rdparty/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp
+++ b/src/3rdparty/angle/src/compiler/timing/RestrictVertexShaderTiming.cpp
@@ -10,8 +10,8 @@ void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node)
{
if (IsSampler(node->getBasicType())) {
++mNumErrors;
- mSink.prefix(EPrefixError);
- mSink.location(node->getLine());
- mSink << "Samplers are not permitted in vertex shaders.\n";
+ mSink.message(EPrefixError,
+ node->getLine(),
+ "Samplers are not permitted in vertex shaders");
}
}
diff --git a/src/3rdparty/angle/src/compiler/util.cpp b/src/3rdparty/angle/src/compiler/util.cpp
index b46e4d0e34..d6e5eeed91 100644
--- a/src/3rdparty/angle/src/compiler/util.cpp
+++ b/src/3rdparty/angle/src/compiler/util.cpp
@@ -4,30 +4,25 @@
// found in the LICENSE file.
//
-#include <math.h>
-#include <stdlib.h>
+#include "compiler/util.h"
-#include "util.h"
+#include <limits>
-#ifdef _MSC_VER
- #include <locale.h>
-#else
- #include <sstream>
-#endif
+#include "compiler/preprocessor/numeric_lex.h"
-double atof_dot(const char *str)
+bool atof_clamp(const char *str, float *value)
{
-#ifdef _MSC_VER
- _locale_t l = _create_locale(LC_NUMERIC, "C");
- double result = _atof_l(str, l);
- _free_locale(l);
- return result;
-#else
- double result;
- std::istringstream s(str);
- std::locale l("C");
- s.imbue(l);
- s >> result;
- return result;
-#endif
+ bool success = pp::numeric_lex_float(str, value);
+ if (!success)
+ *value = std::numeric_limits<float>::max();
+ return success;
}
+
+bool atoi_clamp(const char *str, int *value)
+{
+ bool success = pp::numeric_lex_int(str, value);
+ if (!success)
+ *value = std::numeric_limits<int>::max();
+ return success;
+}
+
diff --git a/src/3rdparty/angle/src/compiler/util.h b/src/3rdparty/angle/src/compiler/util.h
index 35288b7396..dc69f39060 100644
--- a/src/3rdparty/angle/src/compiler/util.h
+++ b/src/3rdparty/angle/src/compiler/util.h
@@ -7,15 +7,14 @@
#ifndef COMPILER_UTIL_H
#define COMPILER_UTIL_H
-#ifdef __cplusplus
-extern "C" {
-#endif
+// atof_clamp is like atof but
+// 1. it forces C locale, i.e. forcing '.' as decimal point.
+// 2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens.
+// Return false if overflow happens.
+extern bool atof_clamp(const char *str, float *value);
-// atof_dot is like atof but forcing C locale, i.e. forcing '.' as decimal point.
-double atof_dot(const char *str);
-
-#ifdef __cplusplus
-} // end extern "C"
-#endif
+// If overflow happens, clamp the value to INT_MIN or INT_MAX.
+// Return false if overflow happens.
+extern bool atoi_clamp(const char *str, int *value);
#endif // COMPILER_UTIL_H