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
7 changed files with 220 additions and 40 deletions
|
|
@ -652,6 +652,53 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
|
|||
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
|
||||
// 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* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
|
||||
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
|
||||
TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function);
|
||||
TIntermAggregate* handleFunctionPrototype(TSourceLoc, TFunction&);
|
||||
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*, TIntermAggregate*);
|
||||
TFunction* handleConstructorCall(TSourceLoc, TPublicType&);
|
||||
|
|
|
|||
|
|
@ -791,45 +791,8 @@ identifier_list
|
|||
|
||||
function_prototype
|
||||
: function_declarator RIGHT_PAREN {
|
||||
// ES can't declare prototypes inside functions
|
||||
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;
|
||||
$$.function = parseContext.handleFunctionDeclarator($2.loc, *$1);
|
||||
$$.loc = $2.loc;
|
||||
|
||||
if (! parseContext.symbolTable.insert(*$$.function))
|
||||
parseContext.error($2.loc, "illegal redeclaration", $$.function->getName().c_str(), "");
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue