Allow ES version 100 to redeclare built-in functions.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23322 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
447fc3613a
commit
44e8cae80a
64
Test/100scope.vert
Normal file
64
Test/100scope.vert
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
int f(int a, int b, int c)
|
||||||
|
{
|
||||||
|
int a = b; // ERROR, redefinition
|
||||||
|
|
||||||
|
{
|
||||||
|
float a = float(a) + 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f(int a, int b, int c); // okay to redeclare
|
||||||
|
|
||||||
|
bool b;
|
||||||
|
float b(int a); // ERROR: redefinition
|
||||||
|
|
||||||
|
float f; // ERROR: redefinition
|
||||||
|
float tan; // ERROR: redefines built-in function
|
||||||
|
float sin(float x); // ERROR: can't overload built-in functions
|
||||||
|
float cos(float x) // ERROR: can't overload built-in functions
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
invariant gl_Position;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int g(); // ERROR: no local function declarations
|
||||||
|
g();
|
||||||
|
|
||||||
|
float sin; // okay
|
||||||
|
sin;
|
||||||
|
|
||||||
|
f(1,2,3);
|
||||||
|
|
||||||
|
float f; // hides f()
|
||||||
|
f = 3.0;
|
||||||
|
|
||||||
|
gl_Position = vec4(f);
|
||||||
|
|
||||||
|
for (int f = 0; f < 10; ++f)
|
||||||
|
++f;
|
||||||
|
|
||||||
|
int x = 1;
|
||||||
|
{
|
||||||
|
float x = 2.0, /* 2nd x visible here */ y = x; // y is initialized to 2
|
||||||
|
int z = z; // ERROR: z not previously defined.
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int x = x; // x is initialized to '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
{
|
||||||
|
S S = S(0); // 'S' is only visible as a struct and constructor
|
||||||
|
S.x; // 'S' is now visible as a variable
|
||||||
|
}
|
||||||
|
}
|
104
Test/baseResults/100scope.vert.out
Normal file
104
Test/baseResults/100scope.vert.out
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
ERROR: 0:5: 'a' : redefinition
|
||||||
|
ERROR: 0:17: 'b' : illegal redeclaration
|
||||||
|
ERROR: 0:19: 'f' : redefinition
|
||||||
|
ERROR: 0:20: 'tan' : redefinition
|
||||||
|
ERROR: 0:31: 'local function declaration' : not supported with this profile: es
|
||||||
|
ERROR: 0:50: 'z' : undeclared identifier
|
||||||
|
ERROR: 0:50: 'z' : redefinition
|
||||||
|
ERROR: 7 compilation errors. No code generated.
|
||||||
|
|
||||||
|
ERROR: node is still EOpNull!
|
||||||
|
0:3 Function Definition: f(i1;i1;i1; (highp int)
|
||||||
|
0:3 Function Parameters:
|
||||||
|
0:3 'a' (in highp int)
|
||||||
|
0:3 'b' (in highp int)
|
||||||
|
0:3 'c' (in highp int)
|
||||||
|
0:? Sequence
|
||||||
|
0:8 Sequence
|
||||||
|
0:8 Sequence
|
||||||
|
0:8 move second child to first child (highp float)
|
||||||
|
0:8 'a' (highp float)
|
||||||
|
0:8 add (highp float)
|
||||||
|
0:8 Convert int to float (highp float)
|
||||||
|
0:8 'a' (in highp int)
|
||||||
|
0:8 Constant:
|
||||||
|
0:8 1.000000
|
||||||
|
0:11 Branch: Return with expression
|
||||||
|
0:11 'a' (in highp int)
|
||||||
|
0:22 Function Definition: cos(f1; (highp float)
|
||||||
|
0:22 Function Parameters:
|
||||||
|
0:22 'x' (in highp float)
|
||||||
|
0:24 Sequence
|
||||||
|
0:24 Branch: Return with expression
|
||||||
|
0:24 Constant:
|
||||||
|
0:24 1.000000
|
||||||
|
0:29 Function Definition: main( (void)
|
||||||
|
0:29 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:32 Function Call: g( (highp int)
|
||||||
|
0:35 'sin' (highp float)
|
||||||
|
0:37 Function Call: f(i1;i1;i1; (highp int)
|
||||||
|
0:37 Constant:
|
||||||
|
0:37 1 (const int)
|
||||||
|
0:37 Constant:
|
||||||
|
0:37 2 (const int)
|
||||||
|
0:37 Constant:
|
||||||
|
0:37 3 (const int)
|
||||||
|
0:40 move second child to first child (highp float)
|
||||||
|
0:40 'f' (highp float)
|
||||||
|
0:40 Constant:
|
||||||
|
0:40 3.000000
|
||||||
|
0:42 move second child to first child (highp 4-component vector of float)
|
||||||
|
0:42 'gl_Position' (invariant gl_Position highp 4-component vector of float)
|
||||||
|
0:42 Construct vec4 (highp 4-component vector of float)
|
||||||
|
0:42 'f' (highp float)
|
||||||
|
0:44 Sequence
|
||||||
|
0:44 Sequence
|
||||||
|
0:44 move second child to first child (highp int)
|
||||||
|
0:44 'f' (highp int)
|
||||||
|
0:44 Constant:
|
||||||
|
0:44 0 (const int)
|
||||||
|
0:44 Loop with condition tested first
|
||||||
|
0:44 Loop Condition
|
||||||
|
0:44 Compare Less Than (bool)
|
||||||
|
0:44 'f' (highp int)
|
||||||
|
0:44 Constant:
|
||||||
|
0:44 10 (const int)
|
||||||
|
0:44 Loop Body
|
||||||
|
0:45 Pre-Increment (highp int)
|
||||||
|
0:45 'f' (highp int)
|
||||||
|
0:44 Loop Terminal Expression
|
||||||
|
0:44 Pre-Increment (highp int)
|
||||||
|
0:44 'f' (highp int)
|
||||||
|
0:47 Sequence
|
||||||
|
0:47 move second child to first child (highp int)
|
||||||
|
0:47 'x' (highp int)
|
||||||
|
0:47 Constant:
|
||||||
|
0:47 1 (const int)
|
||||||
|
0:49 Sequence
|
||||||
|
0:49 Sequence
|
||||||
|
0:49 move second child to first child (highp float)
|
||||||
|
0:49 'x' (highp float)
|
||||||
|
0:49 Constant:
|
||||||
|
0:49 2.000000
|
||||||
|
0:49 move second child to first child (highp float)
|
||||||
|
0:49 'y' (highp float)
|
||||||
|
0:49 'x' (highp float)
|
||||||
|
0:53 Sequence
|
||||||
|
0:53 Sequence
|
||||||
|
0:53 move second child to first child (highp int)
|
||||||
|
0:53 'x' (highp int)
|
||||||
|
0:53 'x' (highp int)
|
||||||
|
0:61 Sequence
|
||||||
|
0:61 Sequence
|
||||||
|
0:61 move second child to first child (structure)
|
||||||
|
0:61 'S' (structure)
|
||||||
|
0:61 Constant:
|
||||||
|
0:61 0 (const int)
|
||||||
|
0:62 x: direct index for structure (highp int)
|
||||||
|
0:62 'S' (structure)
|
||||||
|
0:62 Constant:
|
||||||
|
0:62 0 (const int)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'b' (bool)
|
||||||
|
|
@ -2,8 +2,8 @@ ERROR: 0:5: 'a' : redefinition
|
|||||||
ERROR: 0:17: 'b' : illegal redeclaration
|
ERROR: 0:17: 'b' : illegal redeclaration
|
||||||
ERROR: 0:19: 'f' : redefinition
|
ERROR: 0:19: 'f' : redefinition
|
||||||
ERROR: 0:20: 'tan' : redefinition
|
ERROR: 0:20: 'tan' : redefinition
|
||||||
ERROR: 0:21: 'redeclaration of built-in function' : not supported with this profile: es
|
ERROR: 0:21: 'redeclaration of built-in function' : no longer supported in es profile; removed in version 300
|
||||||
ERROR: 0:22: 'redeclaration of built-in function' : not supported with this profile: es
|
ERROR: 0:22: 'redeclaration of built-in function' : no longer supported in es profile; removed in version 300
|
||||||
ERROR: 0:31: 'local function declaration' : not supported with this profile: es
|
ERROR: 0:31: 'local function declaration' : not supported with this profile: es
|
||||||
ERROR: 0:50: 'z' : undeclared identifier
|
ERROR: 0:50: 'z' : undeclared identifier
|
||||||
ERROR: 0:50: 'z' : redefinition
|
ERROR: 0:50: 'z' : redefinition
|
||||||
|
@ -39,6 +39,7 @@ forwardRef.frag
|
|||||||
uint.frag
|
uint.frag
|
||||||
switch.frag
|
switch.frag
|
||||||
tokenLength.vert
|
tokenLength.vert
|
||||||
|
100scope.vert
|
||||||
300scope.vert
|
300scope.vert
|
||||||
400.frag
|
400.frag
|
||||||
420.vert
|
420.vert
|
||||||
|
@ -652,6 +652,53 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle seeing a function declarator in the grammar. This is the precursor
|
||||||
|
// to recognizing a function prototype or function definition.
|
||||||
|
//
|
||||||
|
TFunction* TParseContext::handleFunctionDeclarator(TSourceLoc loc, TFunction& function)
|
||||||
|
{
|
||||||
|
// ES can't declare prototypes inside functions
|
||||||
|
if (! symbolTable.atGlobalLevel())
|
||||||
|
requireProfile(loc, static_cast<EProfileMask>(~EEsProfileMask), "local function declaration");
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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 (full prototype match) are allowed. But, return types and parameter qualifiers must match.
|
||||||
|
//
|
||||||
|
// ES does not allow redeclaring or hiding of built-in functions.
|
||||||
|
//
|
||||||
|
bool builtIn;
|
||||||
|
TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
|
||||||
|
if (symbol && symbol->getAsFunction() && builtIn)
|
||||||
|
requireNotRemoved(loc, EEsProfile, 300, "redeclaration of built-in function");
|
||||||
|
const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
|
||||||
|
if (prevDec) {
|
||||||
|
if (prevDec->getReturnType() != function.getReturnType()) {
|
||||||
|
error(loc, "overloaded functions must have the same return type", function.getReturnType().getCompleteTypeString().c_str(), "");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < prevDec->getParamCount(); ++i) {
|
||||||
|
if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
|
||||||
|
error(loc, "overloaded functions must have the same parameter qualifiers", function[i].type->getStorageQualifierString(), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (! symbolTable.insert(function))
|
||||||
|
error(loc, "illegal redeclaration", function.getName().c_str(), "");
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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 this declaration, not the one in the symbol table.
|
||||||
|
//
|
||||||
|
return &function;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Handle seeing a function prototype in the grammar. This includes what may
|
// Handle seeing a function prototype in the grammar. This includes what may
|
||||||
// become a full definition, as a full definition looks like a prototype
|
// become a full definition, as a full definition looks like a prototype
|
||||||
|
@ -85,6 +85,7 @@ public:
|
|||||||
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
|
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
|
||||||
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
|
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
|
||||||
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
|
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
|
||||||
|
TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function);
|
||||||
TIntermAggregate* handleFunctionPrototype(TSourceLoc, TFunction&);
|
TIntermAggregate* handleFunctionPrototype(TSourceLoc, TFunction&);
|
||||||
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*, TIntermAggregate*);
|
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*, TIntermAggregate*);
|
||||||
TFunction* handleConstructorCall(TSourceLoc, TPublicType&);
|
TFunction* handleConstructorCall(TSourceLoc, TPublicType&);
|
||||||
|
@ -791,45 +791,8 @@ identifier_list
|
|||||||
|
|
||||||
function_prototype
|
function_prototype
|
||||||
: function_declarator RIGHT_PAREN {
|
: function_declarator RIGHT_PAREN {
|
||||||
// ES can't declare prototypes inside functions
|
$$.function = parseContext.handleFunctionDeclarator($2.loc, *$1);
|
||||||
if (! parseContext.symbolTable.atGlobalLevel())
|
|
||||||
parseContext.requireProfile($2.loc, static_cast<EProfileMask>(~EEsProfileMask), "local function declaration");
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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 (full prototype match) are allowed. But, return types and parameter qualifiers must match.
|
|
||||||
//
|
|
||||||
// ES does not allow redeclaring or hiding of built-in functions.
|
|
||||||
//
|
|
||||||
bool builtIn;
|
|
||||||
TSymbol* symbol = parseContext.symbolTable.find($1->getMangledName(), &builtIn);
|
|
||||||
if (symbol && symbol->getAsFunction() && builtIn)
|
|
||||||
parseContext.requireProfile($2.loc, static_cast<EProfileMask>(~EEsProfileMask), "redeclaration of built-in function");
|
|
||||||
const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
|
|
||||||
if (prevDec) {
|
|
||||||
if (prevDec->getReturnType() != $1->getReturnType()) {
|
|
||||||
parseContext.error($2.loc, "overloaded functions must have the same return type", $1->getReturnType().getCompleteTypeString().c_str(), "");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < prevDec->getParamCount(); ++i) {
|
|
||||||
if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage)
|
|
||||||
parseContext.error($2.loc, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getStorageQualifierString(), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
$$.loc = $2.loc;
|
$$.loc = $2.loc;
|
||||||
|
|
||||||
if (! parseContext.symbolTable.insert(*$$.function))
|
|
||||||
parseContext.error($2.loc, "illegal redeclaration", $$.function->getName().c_str(), "");
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user