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
|
|
@ -9,5 +9,5 @@
|
|||
// source have to figure out how to create revision.h just to get a build
|
||||
// going. However, if it is not updated, it can be a version behind.
|
||||
|
||||
#define GLSLANG_REVISION "24420"
|
||||
#define GLSLANG_DATE "2013/12/09 17:25:14"
|
||||
#define GLSLANG_REVISION "24468"
|
||||
#define GLSLANG_DATE "2013/12/11 11:57:40"
|
||||
|
|
|
|||
|
|
@ -2904,6 +2904,11 @@ const TFunction* TParseContext::findFunction(TSourceLoc loc, const TFunction& ca
|
|||
{
|
||||
const TFunction* function = 0;
|
||||
|
||||
if (symbolTable.isFunctionNameVariable(call.getName())) {
|
||||
error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (profile == EEsProfile || version < 120)
|
||||
function = findFunctionExact(loc, call, builtIn);
|
||||
else if (version < 400)
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ void InitializeStageSymbolTable(TBuiltIns& builtIns, int version, EProfile profi
|
|||
IdentifyBuiltIns(version, profile, language, *symbolTables[language]);
|
||||
if (profile == EEsProfile && version >= 300)
|
||||
(*symbolTables[language]).setNoBuiltInRedeclarations();
|
||||
if (version == 110)
|
||||
(*symbolTables[language]).setSeparateNameSpaces();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -322,11 +322,11 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
|||
TVariable* container = anon->getAnonContainer().clone();
|
||||
container->changeName(NewPoolTString(""));
|
||||
// insert the whole container
|
||||
symTableLevel->insert(*container);
|
||||
symTableLevel->insert(*container, false);
|
||||
containerCopied[anon->getAnonId()] = true;
|
||||
}
|
||||
} else
|
||||
symTableLevel->insert(*iter->second->clone());
|
||||
symTableLevel->insert(*iter->second->clone(), false);
|
||||
}
|
||||
|
||||
return symTableLevel;
|
||||
|
|
@ -338,6 +338,7 @@ void TSymbolTable::copyTable(const TSymbolTable& copyOf)
|
|||
|
||||
uniqueId = copyOf.uniqueId;
|
||||
noBuiltInRedeclarations = copyOf.noBuiltInRedeclarations;
|
||||
separateNameSpaces = copyOf.separateNameSpaces;
|
||||
for (unsigned int i = copyOf.adoptedLevels; i < copyOf.table.size(); ++i)
|
||||
table.push_back(copyOf.table[i]->clone());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
|||
else if (vertices != unit.vertices)
|
||||
error(infoSink, "Contradictory layout max_vertices values");
|
||||
|
||||
if (vertexSpacing == ElgNone)
|
||||
if (vertexSpacing == EvsNone)
|
||||
vertexSpacing = unit.vertexSpacing;
|
||||
else if (vertexSpacing != unit.vertexSpacing)
|
||||
error(infoSink, "Contradictory input vertex spacing");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue