Implement user-defined name hashing.
ANGLEBUG=315
Review URL: https://codereview.appspot.com/6818109
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1469 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputGLSLBase.cpp b/src/compiler/OutputGLSLBase.cpp
index 552fa50..ed86c68 100644
--- a/src/compiler/OutputGLSLBase.cpp
+++ b/src/compiler/OutputGLSLBase.cpp
@@ -9,35 +9,6 @@
namespace
{
-TString getTypeName(const TType& type)
-{
- TInfoSinkBase out;
- if (type.isMatrix())
- {
- out << "mat";
- out << type.getNominalSize();
- }
- else if (type.isVector())
- {
- switch (type.getBasicType())
- {
- case EbtFloat: out << "vec"; break;
- case EbtInt: out << "ivec"; break;
- case EbtBool: out << "bvec"; break;
- default: UNREACHABLE(); break;
- }
- out << type.getNominalSize();
- }
- else
- {
- if (type.getBasicType() == EbtStruct)
- out << type.getTypeName();
- else
- out << type.getBasicString();
- }
- return TString(out.c_str());
-}
-
TString arrayBrackets(const TType& type)
{
ASSERT(type.isArray());
@@ -66,10 +37,16 @@
}
} // namespace
-TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink)
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
- mDeclaringVariables(false)
+ mDeclaringVariables(false),
+ mHashFunction(hashFunction),
+ mNameMap(nameMap),
+ mSymbolTable(symbolTable)
{
}
@@ -101,7 +78,7 @@
if ((type.getBasicType() == EbtStruct) &&
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{
- out << "struct " << type.getTypeName() << "{\n";
+ out << "struct " << hashName(type.getTypeName()) << "{\n";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
@@ -110,7 +87,7 @@
ASSERT(fieldType != NULL);
if (writeVariablePrecision(fieldType->getPrecision()))
out << " ";
- out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
+ out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
@@ -140,7 +117,7 @@
const TString& name = arg->getSymbol();
if (!name.empty())
- out << " " << name;
+ out << " " << hashName(name);
if (type.isArray())
out << arrayBrackets(type);
@@ -157,7 +134,7 @@
if (type.getBasicType() == EbtStruct)
{
- out << type.getTypeName() << "(";
+ out << hashName(type.getTypeName()) << "(";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
@@ -196,7 +173,7 @@
if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
out << mLoopUnroll.GetLoopIndexValue(node);
else
- out << node->getSymbol();
+ out << hashVariableName(node->getSymbol());
if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType());
@@ -243,7 +220,7 @@
{
out << ".";
// TODO(alokp): ASSERT
- out << node->getType().getFieldName();
+ out << hashName(node->getType().getFieldName());
visitChildren = false;
}
break;
@@ -467,7 +444,7 @@
// Function declaration.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << node->getName();
+ out << " " << hashName(node->getName());
out << "(";
writeFunctionParameters(node->getSequence());
@@ -480,7 +457,7 @@
// Function definition.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << TFunction::unmangleName(node->getName());
+ out << " " << hashFunctionName(node->getName());
incrementDepth();
// Function definition node contains one or two children nodes
@@ -510,8 +487,7 @@
// Function call.
if (visit == PreVisit)
{
- TString functionName = TFunction::unmangleName(node->getName());
- out << functionName << "(";
+ out << hashFunctionName(node->getName()) << "(";
}
else if (visit == InVisit)
{
@@ -572,7 +548,7 @@
{
const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct);
- out << type.getTypeName() << "(";
+ out << hashName(type.getTypeName()) << "(";
}
else if (visit == InVisit)
{
@@ -718,3 +694,59 @@
out << "{\n}\n"; // Empty code block.
}
}
+
+TString TOutputGLSLBase::getTypeName(const TType& type)
+{
+ TInfoSinkBase out;
+ if (type.isMatrix())
+ {
+ out << "mat";
+ out << type.getNominalSize();
+ }
+ else if (type.isVector())
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat: out << "vec"; break;
+ case EbtInt: out << "ivec"; break;
+ case EbtBool: out << "bvec"; break;
+ default: UNREACHABLE(); break;
+ }
+ out << type.getNominalSize();
+ }
+ else
+ {
+ if (type.getBasicType() == EbtStruct)
+ out << hashName(type.getTypeName());
+ else
+ out << type.getBasicString();
+ }
+ return TString(out.c_str());
+}
+
+TString TOutputGLSLBase::hashName(const TString& name)
+{
+ if (mHashFunction == NULL || name.empty())
+ return name;
+ NameMap::const_iterator it = mNameMap.find(name.c_str());
+ if (it != mNameMap.end())
+ return it->second.c_str();
+ TString hashedName = TIntermTraverser::hash(name, mHashFunction);
+ mNameMap[name.c_str()] = hashedName.c_str();
+ return hashedName;
+}
+
+TString TOutputGLSLBase::hashVariableName(const TString& name)
+{
+ if (mSymbolTable.findBuiltIn(name) != NULL)
+ return name;
+ return hashName(name);
+}
+
+TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
+{
+ TString name = TFunction::unmangleName(mangled_name);
+ if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main")
+ return name;
+ return hashName(name);
+}