Detect redefinition of function name as variable.

We were previously already detecting when a variable name was redefined
as a function, but not the inverse. The fix involves inserting the
unmangled function name into the symbol table.

Change-Id: I0efd1309d45f004c8d1c5ceb864e08c2ebe22f1d
Reviewed-on: https://swiftshader-review.googlesource.com/16048
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/compiler/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index 7e7667d..090faa8 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -427,10 +427,10 @@
 	fields->push_back(diff);
 	TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
 	TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
-	symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters);
+	symbolTable.insert(COMMON_BUILTINS, depthRangeParameters);
 	TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
 	depthRange->setQualifier(EvqUniform);
-	symbolTable.insert(COMMON_BUILTINS, *depthRange);
+	symbolTable.insert(COMMON_BUILTINS, depthRange);
 
 	//
 	// Implementation dependent built-in constants.
@@ -460,18 +460,18 @@
 	switch(shaderType)
 	{
 	case GL_FRAGMENT_SHADER:
-		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
-		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
-		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
-		symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
-		symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
-		symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
+		symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
+		symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
+		symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
+		symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
+		symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
+		symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
 		break;
 	case GL_VERTEX_SHADER:
-		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
-		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
-		symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
-		symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
+		symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
+		symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
+		symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
+		symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
 		break;
 	default: assert(false && "Language not supported");
 	}
@@ -484,7 +484,7 @@
 			// Set up gl_FragData.  The array size.
 			TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
 			fragData.setArraySize(resources.MaxDrawBuffers);
-			symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData));
+			symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
 		}
 		break;
 	default: break;
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index 1dbe682..a7d7d01 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -1018,7 +1018,7 @@
 		return false;
 
 	(*variable) = new TVariable(&identifier, type);
-	if(!symbolTable.declare(**variable))
+	if(!symbolTable.declare(*variable))
 	{
 		error(line, "redefinition", identifier.c_str());
 		delete (*variable);
@@ -1186,7 +1186,7 @@
 	{
 		TType type(EbtFloat, EbpUndefined);
 		TVariable *fakeVariable = new TVariable(name, type);
-		symbolTable.declare(*fakeVariable);
+		symbolTable.declare(fakeVariable);
 		variable = fakeVariable;
 	}
 
@@ -1203,11 +1203,11 @@
 	// First find by unmangled name to check whether the function name has been
 	// hidden by a variable name or struct typename.
 	const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
-	if (symbol == 0) {
+	if (!symbol || symbol->isFunction()) {
 		symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
 	}
 
-	if (symbol == 0) {
+	if (!symbol) {
 		error(line, "no matching overloaded function found", call->getName().c_str());
 		return nullptr;
 	}
@@ -1965,7 +1965,7 @@
 			//
 			// Insert the parameters with name in the symbol table.
 			//
-			if(!symbolTable.declare(*variable))
+			if(!symbolTable.declare(variable))
 			{
 				error(location, "redefinition", variable->getName().c_str());
 				recover();
@@ -2041,10 +2041,16 @@
 			recover();
 		}
 	}
+	else
+	{
+		// Insert the unmangled name to detect potential future redefinition as a variable.
+		TFunction *unmangledFunction = new TFunction(NewPoolTString(function->getName().c_str()), function->getReturnType());
+		symbolTable.getOuterLevel()->insertUnmangled(unmangledFunction);
+	}
 
 	// We're at the inner scope level of the function's arguments and body statement.
 	// Add the function prototype to the surrounding scope instead.
-	symbolTable.getOuterLevel()->insert(*function);
+	symbolTable.getOuterLevel()->insert(function);
 
 	//
 	// If this is a redeclaration, it could also be a definition, in which case, we want to use the
@@ -2344,7 +2350,7 @@
 	}
 
 	TSymbol* blockNameSymbol = new TSymbol(&blockName);
-	if(!symbolTable.declare(*blockNameSymbol)) {
+	if(!symbolTable.declare(blockNameSymbol)) {
 		error(nameLine, "redefinition", blockName.c_str(), "interface block name");
 		recover();
 	}
@@ -2423,7 +2429,7 @@
 			TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
 			fieldVariable->setQualifier(typeQualifier.qualifier);
 
-			if(!symbolTable.declare(*fieldVariable)) {
+			if(!symbolTable.declare(fieldVariable)) {
 				error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
 				recover();
 			}
@@ -2438,7 +2444,7 @@
 		TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
 		instanceTypeDef->setQualifier(typeQualifier.qualifier);
 
-		if(!symbolTable.declare(*instanceTypeDef)) {
+		if(!symbolTable.declare(instanceTypeDef)) {
 			error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
 			recover();
 		}
@@ -2972,7 +2978,7 @@
 			recover();
 		}
 		TVariable *userTypeDef = new TVariable(structName, *structureType, true);
-		if(!symbolTable.declare(*userTypeDef))
+		if(!symbolTable.declare(userTypeDef))
 		{
 			error(nameLine, "redefinition", structName->c_str(), "struct");
 			recover();
diff --git a/src/OpenGL/compiler/SymbolTable.cpp b/src/OpenGL/compiler/SymbolTable.cpp
index b2e48e8..22bf292 100644
--- a/src/OpenGL/compiler/SymbolTable.cpp
+++ b/src/OpenGL/compiler/SymbolTable.cpp
@@ -27,8 +27,8 @@
 #include <limits.h>
 #include <algorithm>
 
-#if defined(_MSC_VER) && MSC_VER < 1900

-#define snprintf _snprintf

+#if defined(_MSC_VER) && MSC_VER < 1900
+#define snprintf _snprintf
 #endif
 
 int TSymbolTableLevel::uniqueId = 0;
@@ -195,6 +195,35 @@
 		delete (*it).second;
 }
 
+bool TSymbolTableLevel::insert(TSymbol *symbol)
+{
+	symbol->setUniqueId(nextUniqueId());
+
+	// returning true means symbol was added to the table
+	tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
+
+	return result.second;
+}
+
+bool TSymbolTableLevel::insertUnmangled(TFunction *function)
+{
+	function->setUniqueId(nextUniqueId());
+
+	// returning true means symbol was added to the table
+	tInsertResult result = level.insert(tLevelPair(function->getName(), function));
+
+	return result.second;
+}
+
+TSymbol *TSymbolTableLevel::find(const TString &name) const
+{
+	tLevel::const_iterator it = level.find(name);
+	if (it == level.end())
+		return 0;
+	else
+		return (*it).second;
+}
+
 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
 {
 	int level = currentLevel();
diff --git a/src/OpenGL/compiler/SymbolTable.h b/src/OpenGL/compiler/SymbolTable.h
index c4fdbfe..3bc7ff4 100644
--- a/src/OpenGL/compiler/SymbolTable.h
+++ b/src/OpenGL/compiler/SymbolTable.h
@@ -206,27 +206,12 @@
 	TSymbolTableLevel() { }
 	~TSymbolTableLevel();
 
-	bool insert(TSymbol &symbol)
-	{
-		symbol.setUniqueId(nextUniqueId());
+	bool insert(TSymbol *symbol);
 
-		//
-		// returning true means symbol was added to the table
-		//
-		tInsertResult result;
-		result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
+    // Insert a function using its unmangled name as the key.
+    bool insertUnmangled(TFunction *function);
 
-		return result.second;
-	}
-
-	TSymbol* find(const TString& name) const
-	{
-		tLevel::const_iterator it = level.find(name);
-		if (it == level.end())
-			return 0;
-		else
-			return (*it).second;
-	}
+    TSymbol *find(const TString &name) const;
 
 	static int nextUniqueId()
 	{
@@ -348,12 +333,12 @@
 		precisionStack.pop_back();
 	}
 
-	bool declare(TSymbol &symbol)
+	bool declare(TSymbol *symbol)
 	{
 		return insert(currentLevel(), symbol);
 	}
 
-	bool insert(ESymbolLevel level, TSymbol &symbol)
+	bool insert(ESymbolLevel level, TSymbol *symbol)
 	{
 		return table[level]->insert(symbol);
 	}
@@ -362,7 +347,7 @@
 	{
 		TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConstExpr, 1));
 		constant->getConstPointer()->setIConst(value);
-		return insert(level, *constant);
+		return insert(level, constant);
 	}
 
 	void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
@@ -448,7 +433,7 @@
 			}
 
 			ASSERT(hasUnmangledBuiltIn(name));
-			insert(level, *function);
+			insert(level, function);
 		}
 	}