Add missing check that a function call is not using the same name as a variable hiding the function's name. Also, support version 110 separate name spaces for functions and variable names.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24480 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
623833fabc
commit
3a4687d782
17 changed files with 576 additions and 285 deletions
|
|
@ -283,7 +283,7 @@ public:
|
|||
TSymbolTableLevel() : defaultPrecision(0), anonId(0) { }
|
||||
~TSymbolTableLevel();
|
||||
|
||||
bool insert(TSymbol& symbol)
|
||||
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
||||
{
|
||||
//
|
||||
// returning true means symbol was added to the table with no semantic errors
|
||||
|
|
@ -316,7 +316,7 @@ public:
|
|||
const TString& insertName = symbol.getMangledName();
|
||||
if (symbol.getAsFunction()) {
|
||||
// make sure there isn't a variable of this name
|
||||
if (level.find(name) != level.end())
|
||||
if (! separateNameSpaces && level.find(name) != level.end())
|
||||
return false;
|
||||
|
||||
// insert, and whatever happens is okay
|
||||
|
|
@ -367,6 +367,34 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
// See if there is a variable at this level having the given non-function-style name.
|
||||
// Return true if name is found, and set variable to true if the name was a variable.
|
||||
bool findFunctionVariableName(const TString& name, bool& variable) const
|
||||
{
|
||||
tLevel::const_iterator candidate = level.lower_bound(name);
|
||||
if (candidate != level.end()) {
|
||||
const TString& candidateName = (*candidate).first;
|
||||
TString::size_type parenAt = candidateName.find_first_of('(');
|
||||
if (parenAt == candidateName.npos) {
|
||||
// not a mangled name
|
||||
if (candidateName == name) {
|
||||
// found a variable name match
|
||||
variable = true;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// a mangled name
|
||||
if (candidateName.compare(0, parenAt, name) == 0) {
|
||||
// found a function name match
|
||||
variable = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use this to do a lazy 'push' of precision defaults the first time
|
||||
// a precision statement is seen in a new scope. Leave it at 0 for
|
||||
// when no push was needed. Thus, it is not the current defaults,
|
||||
|
|
@ -415,7 +443,7 @@ protected:
|
|||
|
||||
class TSymbolTable {
|
||||
public:
|
||||
TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), adoptedLevels(0)
|
||||
TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0)
|
||||
{
|
||||
//
|
||||
// This symbol table cannot be used until push() is called.
|
||||
|
|
@ -438,6 +466,7 @@ public:
|
|||
}
|
||||
uniqueId = symTable.uniqueId;
|
||||
noBuiltInRedeclarations = symTable.noBuiltInRedeclarations;
|
||||
separateNameSpaces = symTable.separateNameSpaces;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -459,6 +488,7 @@ public:
|
|||
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
|
||||
|
||||
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
|
||||
void setSeparateNameSpaces() { separateNameSpaces = true; }
|
||||
|
||||
void push()
|
||||
{
|
||||
|
|
@ -477,7 +507,7 @@ public:
|
|||
symbol.setUniqueId(++uniqueId);
|
||||
|
||||
// make sure there isn't a function of this variable name
|
||||
if (! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
|
||||
if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
|
||||
return false;
|
||||
|
||||
// check for not overloading or redefining a built-in function
|
||||
|
|
@ -490,7 +520,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
return table[currentLevel()]->insert(symbol);
|
||||
return table[currentLevel()]->insert(symbol, separateNameSpaces);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -517,12 +547,12 @@ public:
|
|||
TSymbol* copyUp(TSymbol* shared)
|
||||
{
|
||||
TSymbol* copy = copyUpDeferredInsert(shared);
|
||||
table[globalLevel]->insert(*copy);
|
||||
table[globalLevel]->insert(*copy, separateNameSpaces);
|
||||
if (shared->getAsVariable())
|
||||
return copy;
|
||||
else {
|
||||
// get copy of an anonymous member's container
|
||||
table[currentLevel()]->insert(*copy);
|
||||
table[currentLevel()]->insert(*copy, separateNameSpaces);
|
||||
// return the copy of the anonymous member
|
||||
return table[currentLevel()]->find(shared->getName());
|
||||
}
|
||||
|
|
@ -545,6 +575,23 @@ public:
|
|||
return symbol;
|
||||
}
|
||||
|
||||
bool isFunctionNameVariable(const TString& name) const
|
||||
{
|
||||
if (separateNameSpaces)
|
||||
return false;
|
||||
|
||||
int level = currentLevel();
|
||||
do {
|
||||
bool variable;
|
||||
bool found = table[level]->findFunctionVariableName(name, variable);
|
||||
if (found)
|
||||
return variable;
|
||||
--level;
|
||||
} while (level >= 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void findFunctionNameList(const TString& name, TVector<TFunction*>& list, bool& builtIn)
|
||||
{
|
||||
// For user levels, return the set found in the first scope with a match
|
||||
|
|
@ -606,6 +653,7 @@ protected:
|
|||
std::vector<TSymbolTableLevel*> table;
|
||||
int uniqueId; // for unique identification in code generation
|
||||
bool noBuiltInRedeclarations;
|
||||
bool separateNameSpaces;
|
||||
unsigned int adoptedLevels;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue