Skip symbol table levels with built-ins for a different shader version.

TRAC #22954
Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2272 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index 5deda55..bd08fa5 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -741,7 +741,7 @@
 
     bool builtIn = false; 
     bool sameScope = false;
-    TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
+    TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
     if (symbol == 0 || !sameScope) {
         if (reservedErrorCheck(line, identifier))
             return true;
@@ -800,7 +800,7 @@
 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
 {
     bool builtIn = false;
-    TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
+    TSymbol* symbol = symbolTable.find(node->getSymbol(), 0, &builtIn);
     if (symbol == 0) {
         error(line, " undeclared identifier", node->getSymbol().c_str());
         return true;
@@ -813,7 +813,7 @@
     // 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);
+        TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", 0, &builtIn);
         ASSERT(fragData);
 
         int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
@@ -970,13 +970,13 @@
 //
 // Return the function symbol if found, otherwise 0.
 //
-const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
+const TFunction* TParseContext::findFunction(int line, TFunction* call, int shaderVersion, bool *builtIn)
 {
     // First find by unmangled name to check whether the function name has been
     // hidden by a variable name or struct typename.
-    const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
+    const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
     if (symbol == 0) {
-        symbol = symbolTable.find(call->getMangledName(), builtIn);
+        symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
     }
 
     if (symbol == 0) {
@@ -1056,7 +1056,7 @@
                 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
             }
         } else if (initializer->getAsSymbolNode()) {
-            const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
+            const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
             const TVariable* tVar = static_cast<const TVariable*>(symbol);
 
             ConstantUnion* constArray = tVar->getConstPointer();
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index ba88336..d99dc60 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -115,7 +115,7 @@
 
     bool containsSampler(TType& type);
     bool areAllChildConst(TIntermAggregate* aggrNode);
-    const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
+    const TFunction* findFunction(int line, TFunction* pfnCall, int shaderVersion, bool *builtIn = 0);
     bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
                             TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
     bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
diff --git a/src/compiler/SymbolTable.cpp b/src/compiler/SymbolTable.cpp
index 847c1e4..ebe2113 100644
--- a/src/compiler/SymbolTable.cpp
+++ b/src/compiler/SymbolTable.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -277,3 +277,41 @@
         precisionStack.push_back( copyOf.precisionStack[i] );
     }
 }
+
+TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
+{
+    int level = currentLevel();
+    TSymbol *symbol;
+
+    do
+    {
+        if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
+        if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
+
+        symbol = table[level]->find(name);
+    }
+    while (symbol == 0 && --level >= 0);
+
+    if (builtIn)
+        *builtIn = (level <= LAST_BUILTIN_LEVEL);
+    if (sameScope)
+        *sameScope = (level == currentLevel());
+
+    return symbol;
+}
+
+TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
+{
+    for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
+    {
+        if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
+        if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
+
+        TSymbol *symbol = table[level]->find(name);
+
+        if (symbol)
+            return symbol;
+    }
+
+    return 0;
+}
diff --git a/src/compiler/SymbolTable.h b/src/compiler/SymbolTable.h
index c429ab2..2f91053 100644
--- a/src/compiler/SymbolTable.h
+++ b/src/compiler/SymbolTable.h
@@ -295,33 +295,8 @@
         return table[level]->insert(symbol);
     }
 
-    TSymbol *find(const TString &name, bool *builtIn = false, bool *sameScope = false) 
-    {
-        int level = currentLevel();
-        TSymbol* symbol;
-        do {
-            symbol = table[level]->find(name);
-            --level;
-        } while (symbol == 0 && level >= 0);
-        level++;
-        if (builtIn)
-            *builtIn = (level <= LAST_BUILTIN_LEVEL);
-        if (sameScope)
-            *sameScope = (level == currentLevel());
-        return symbol;
-    }
-
-    TSymbol *findBuiltIn(const TString &name)
-    {
-        for (int i = LAST_BUILTIN_LEVEL; i >= 0; i--) {
-            TSymbol *symbol = table[i]->find(name);
-
-            if (symbol)
-                return symbol;
-        }
-
-        return 0;
-    }
+    TSymbol *find(const TString &name, int shaderVersion, bool *builtIn = false, bool *sameScope = false);
+    TSymbol *findBuiltIn(const TString &name, int shaderVersion);
     
     TSymbolTableLevel *getOuterLevel() {
         assert(currentLevel() >= 1);
diff --git a/src/compiler/ValidateLimitations.cpp b/src/compiler/ValidateLimitations.cpp
index a5562d0..aeb0d8f 100644
--- a/src/compiler/ValidateLimitations.cpp
+++ b/src/compiler/ValidateLimitations.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.
 //
@@ -436,7 +436,7 @@
 
     bool valid = true;
     TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
-    TSymbol* symbol = symbolTable.find(node->getName());
+    TSymbol* symbol = symbolTable.find(node->getName(), GlobalParseContext->shaderVersion);
     ASSERT(symbol && symbol->isFunction());
     TFunction* function = static_cast<TFunction*>(symbol);
     for (ParamIndex::const_iterator i = pIndex.begin();
diff --git a/src/compiler/glslang.l b/src/compiler/glslang.l
index 30b2130..8ab4ee1 100644
--- a/src/compiler/glslang.l
+++ b/src/compiler/glslang.l
@@ -360,7 +360,7 @@
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
     
     int token = IDENTIFIER;
-    TSymbol* symbol = yyextra->symbolTable.find(yytext);
+    TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion);
     if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
         TVariable* variable = static_cast<TVariable*>(symbol);
         if (variable->isUserType()) {
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index 5107e1c..dec932c 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -497,7 +497,7 @@
             //
             const TFunction* fnCandidate;
             bool builtIn;
-            fnCandidate = context->findFunction($1.line, fnCall, &builtIn);
+            fnCandidate = context->findFunction($1.line, fnCall, context->shaderVersion, &builtIn);
             if (fnCandidate) {
                 //
                 // A declared function.
@@ -1029,7 +1029,7 @@
         //
         // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
         //
-        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName(), context->shaderVersion));
         if (prevDec) {
             if (prevDec->getReturnType() != $1->getReturnType()) {
                 context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
@@ -2144,7 +2144,7 @@
     : function_prototype {
         TFunction* function = $1.function;
         
-        const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName());
+        const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion);
         
         if (builtIn)
         {
@@ -2152,7 +2152,7 @@
             context->recover();
         }
         
-        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName(), context->shaderVersion));
         //
         // Note:  'prevDec' could be 'function' if this is the first time we've seen function
         // as it would have just been put in the symbol table.  Otherwise, we're looking up
diff --git a/src/compiler/glslang_lex.cpp b/src/compiler/glslang_lex.cpp
index 28e1922..0e59aef 100644
--- a/src/compiler/glslang_lex.cpp
+++ b/src/compiler/glslang_lex.cpp
@@ -1,4 +1,4 @@
-#line 17 "./glslang.l"
+
 //
 // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -21,8 +21,6 @@
 
 
 
-#line 25 "./glslang_lex.cpp"
-
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
@@ -3094,7 +3092,7 @@
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
     
     int token = IDENTIFIER;
-    TSymbol* symbol = yyextra->symbolTable.find(yytext);
+    TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion);
     if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
         TVariable* variable = static_cast<TVariable*>(symbol);
         if (variable->isUserType()) {
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index a01fce8..a754341 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -2490,7 +2490,7 @@
             //
             const TFunction* fnCandidate;
             bool builtIn;
-            fnCandidate = context->findFunction((yyvsp[(1) - (1)].interm).line, fnCall, &builtIn);
+            fnCandidate = context->findFunction((yyvsp[(1) - (1)].interm).line, fnCall, context->shaderVersion, &builtIn);
             if (fnCandidate) {
                 //
                 // A declared function.
@@ -3176,7 +3176,7 @@
         //
         // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
         //
-        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName()));
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName(), context->shaderVersion));
         if (prevDec) {
             if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) {
                 context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString());
@@ -4618,7 +4618,7 @@
     {
         TFunction* function = (yyvsp[(1) - (1)].interm).function;
         
-        const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName());
+        const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion);
         
         if (builtIn)
         {
@@ -4626,7 +4626,7 @@
             context->recover();
         }
         
-        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName(), context->shaderVersion));
         //
         // Note:  'prevDec' could be 'function' if this is the first time we've seen function
         // as it would have just been put in the symbol table.  Otherwise, we're looking up