Commit 13e7c7e6 by Geoff Lang

Revert "Names of built-in functions cannot be redeclared as functions"

Causing failures in the WebGL1 test: conformance/glsl/misc/shader-with-non-reserved-words.html This reverts commit b5f88853. Change-Id: I2105c8040057665abda00435e8c0ff8a83af3645 Reviewed-on: https://chromium-review.googlesource.com/289192Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 385a1d31
...@@ -2009,26 +2009,18 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, ...@@ -2009,26 +2009,18 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function) TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
{ {
TFunction *prevDec = static_cast<TFunction*>(symbolTable.find(function->getMangledName(), getShaderVersion())); //
bool builtIn; // Multiple declarations of the same function are allowed.
TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion(), &builtIn); //
if (getShaderVersion() >= 300 && prevSym && builtIn) // If this is a definition, the definition production code will check for redefinitions
{ // (we don't know at this point if it's a definition or not).
// With ESSL 3.00, names of built-in functions cannot be redeclared as functions. //
// Therefore overloading or redefining builtin functions is an error. // Redeclarations are allowed. But, return types and parameter qualifiers must match.
error(location, "Name of a built-in function cannot be redeclared as function", function->getName().c_str()); //
recover(); TFunction *prevDec =
} static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
else if (prevDec) if (prevDec)
{ {
//
// Multiple declarations of the same function are allowed.
//
// If this is a definition, the definition production code will check for redefinitions
// (we don't know at this point if it's a definition or not).
//
// Redeclarations are allowed. But, return types and parameter qualifiers must match.
//
if (prevDec->getReturnType() != function->getReturnType()) if (prevDec->getReturnType() != function->getReturnType())
{ {
error(location, "overloaded functions must have the same return type", error(location, "overloaded functions must have the same return type",
...@@ -2050,6 +2042,7 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF ...@@ -2050,6 +2042,7 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
// //
// Check for previously declared variables using the same name. // Check for previously declared variables using the same name.
// //
TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
if (prevSym) if (prevSym)
{ {
if (!prevSym->isFunction()) if (!prevSym->isFunction())
......
...@@ -199,7 +199,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -199,7 +199,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
{ {
if (ptype1->getBasicType() == EbtGSampler2D) if (ptype1->getBasicType() == EbtGSampler2D)
{ {
insertUnmangled(level, name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
...@@ -207,7 +206,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -207,7 +206,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
} }
else if (ptype1->getBasicType() == EbtGSampler3D) else if (ptype1->getBasicType() == EbtGSampler3D)
{ {
insertUnmangled(level, name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
...@@ -215,7 +213,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -215,7 +213,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
} }
else if (ptype1->getBasicType() == EbtGSamplerCube) else if (ptype1->getBasicType() == EbtGSamplerCube)
{ {
insertUnmangled(level, name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
...@@ -223,7 +220,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -223,7 +220,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
} }
else if (ptype1->getBasicType() == EbtGSampler2DArray) else if (ptype1->getBasicType() == EbtGSampler2DArray)
{ {
insertUnmangled(level, name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
...@@ -232,7 +228,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -232,7 +228,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3)) else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
{ {
ASSERT(!ptype4 && !ptype5); ASSERT(!ptype4 && !ptype5);
insertUnmangled(level, name);
insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1)); insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2)); insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3)); insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
...@@ -241,7 +236,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -241,7 +236,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3)) else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
{ {
ASSERT(!ptype4 && !ptype5); ASSERT(!ptype4 && !ptype5);
insertUnmangled(level, name);
insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2)); insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3)); insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4)); insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
...@@ -272,7 +266,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e ...@@ -272,7 +266,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
function->addParameter(TConstParameter(ptype5)); function->addParameter(TConstParameter(ptype5));
} }
ASSERT(table[level]->find(name));
insert(level, function); insert(level, function);
} }
} }
......
...@@ -418,21 +418,18 @@ class TSymbolTable : angle::NonCopyable ...@@ -418,21 +418,18 @@ class TSymbolTable : angle::NonCopyable
void insertBuiltIn(ESymbolLevel level, const TType *rvalue, const char *name, void insertBuiltIn(ESymbolLevel level, const TType *rvalue, const char *name,
const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0)
{ {
insertUnmangled(level, name);
insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
void insertBuiltIn(ESymbolLevel level, const char *ext, const TType *rvalue, const char *name, void insertBuiltIn(ESymbolLevel level, const char *ext, const TType *rvalue, const char *name,
const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0)
{ {
insertUnmangled(level, name);
insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
void insertBuiltIn(ESymbolLevel level, TOperator op, const TType *rvalue, const char *name, void insertBuiltIn(ESymbolLevel level, TOperator op, const TType *rvalue, const char *name,
const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0)
{ {
insertUnmangled(level, name);
insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
...@@ -494,12 +491,6 @@ class TSymbolTable : angle::NonCopyable ...@@ -494,12 +491,6 @@ class TSymbolTable : angle::NonCopyable
return static_cast<ESymbolLevel>(table.size() - 1); return static_cast<ESymbolLevel>(table.size() - 1);
} }
// Used to insert unmangled functions to check redeclaration of built-ins later for ESSL 3.00.
bool insertUnmangled(ESymbolLevel level, const char *name)
{
return table[level]->insertUnmangled(new TFunction(NewPoolTString(name), new TType()));
}
std::vector<TSymbolTableLevel *> table; std::vector<TSymbolTableLevel *> table;
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel; typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector< PrecisionStackLevel *> precisionStack; std::vector< PrecisionStackLevel *> precisionStack;
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
'<(angle_path)/src/tests/compiler_tests/MalformedShader_test.cpp', '<(angle_path)/src/tests/compiler_tests/MalformedShader_test.cpp',
'<(angle_path)/src/tests/compiler_tests/NV_draw_buffers_test.cpp', '<(angle_path)/src/tests/compiler_tests/NV_draw_buffers_test.cpp',
'<(angle_path)/src/tests/compiler_tests/Pack_Unpack_test.cpp', '<(angle_path)/src/tests/compiler_tests/Pack_Unpack_test.cpp',
'<(angle_path)/src/tests/compiler_tests/ParseESSLFunctions_test.cpp',
'<(angle_path)/src/tests/compiler_tests/PruneUnusedFunctions_test.cpp', '<(angle_path)/src/tests/compiler_tests/PruneUnusedFunctions_test.cpp',
'<(angle_path)/src/tests/compiler_tests/RecordConstantPrecision_test.cpp', '<(angle_path)/src/tests/compiler_tests/RecordConstantPrecision_test.cpp',
'<(angle_path)/src/tests/compiler_tests/RemovePow_test.cpp', '<(angle_path)/src/tests/compiler_tests/RemovePow_test.cpp',
......
//
// Copyright (c) 2015 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.
//
// ParseESSLFunctions_test.cpp:
// Tests for ESSL built-in functons.
//
#include "angle_gl.h"
#include "gtest/gtest.h"
#include "GLSLANG/ShaderLang.h"
#include "compiler/translator/PoolAlloc.h"
#include "compiler/translator/TranslatorESSL.h"
namespace
{
class ParseESSLFunctionsTest : public testing::Test
{
public:
ParseESSLFunctionsTest() {}
protected:
void SetUp()
{
mAllocator.push();
SetGlobalPoolAllocator(&mAllocator);
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
mTranslatorESSL = new TranslatorESSL(GL_VERTEX_SHADER, SH_GLES3_SPEC);
ASSERT_TRUE(mTranslatorESSL->Init(resources));
}
void TearDown()
{
delete mTranslatorESSL;
SetGlobalPoolAllocator(NULL);
mAllocator.pop();
}
bool compile(const std::string& shaderString)
{
const char *shaderStrings[] = { shaderString.c_str() };
return mTranslatorESSL->compileTreeForTesting(shaderStrings, 1, SH_OBJECT_CODE) != nullptr;
}
private:
TranslatorESSL *mTranslatorESSL;
TPoolAllocator mAllocator;
};
// Tests that cimpilation succeeds for built-in function overload in ESSL 1.00.
TEST_F(ParseESSLFunctionsTest, ESSL100BuiltInFunctionOverload)
{
const std::string &shaderString =
"precision mediump float;\n"
"int sin(int x) {\n"
" return int(sin(float(x)));\n"
"}\n"
"void main() {\n"
" gl_Position = vec4(sin(1));"
"}\n";
EXPECT_TRUE(compile(shaderString));
}
// Tests that cimpilation fails for built-in function redefinition in ESSL 1.00.
TEST_F(ParseESSLFunctionsTest, ESSL100BuiltInFunctionRedefinition)
{
const std::string &shaderString =
"precision mediump float;\n"
"float sin(float x) {\n"
" return sin(0.0);\n"
"}\n"
"void main() {\n"
" gl_Position = vec4(sin(1.0));\n"
"}\n";
EXPECT_FALSE(compile(shaderString));
}
} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment