Store symbol names as a ImmutableString
This will enable compile-time initialization of built-in symbols as
well as reducing copying strings.
Most of the code that deals with names is changed to use
ImmutableString where it makes sense to avoid conversions.
The lexer/parser now allocate const char pointers into pool memory
instead of allocating TStrings. These are then converted to
ImmutableString upon entering TParseContext.
BUG=angleproject:2267
TEST=angle_unittests, angle_end2end_tests
Change-Id: I244d6271ea1ecf7150d4f89dfa388a7745a1150c
Reviewed-on: https://chromium-review.googlesource.com/881561
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/ASTMetadataHLSL.cpp b/src/compiler/translator/ASTMetadataHLSL.cpp
index a15fc36..055408d 100644
--- a/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -35,15 +35,15 @@
ASSERT(index < metadataList->size());
// ESSL 100 builtin gradient functions
- mGradientBuiltinFunctions.insert("texture2D");
- mGradientBuiltinFunctions.insert("texture2DProj");
- mGradientBuiltinFunctions.insert("textureCube");
+ mGradientBuiltinFunctions.insert(ImmutableString("texture2D"));
+ mGradientBuiltinFunctions.insert(ImmutableString("texture2DProj"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureCube"));
// ESSL 300 builtin gradient functions
- mGradientBuiltinFunctions.insert("texture");
- mGradientBuiltinFunctions.insert("textureProj");
- mGradientBuiltinFunctions.insert("textureOffset");
- mGradientBuiltinFunctions.insert("textureProjOffset");
+ mGradientBuiltinFunctions.insert(ImmutableString("texture"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureProj"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureOffset"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureProjOffset"));
// ESSL 310 doesn't add builtin gradient functions
}
@@ -151,7 +151,7 @@
std::vector<TIntermNode *> mParents;
// A list of builtin functions that use gradients
- std::set<TString> mGradientBuiltinFunctions;
+ std::set<ImmutableString> mGradientBuiltinFunctions;
};
// Traverses the AST of a function definition to compute the the discontinuous loops
diff --git a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
index 2907f1d..5111aaa 100644
--- a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -21,6 +21,8 @@
namespace
{
+constexpr const ImmutableString kReturnValueVariableName("angle_return");
+
void CopyAggregateChildren(TIntermAggregateBase *from, TIntermAggregateBase *to)
{
const TIntermSequence *fromSequence = from->getSequence();
@@ -58,8 +60,6 @@
// Map from function symbol ids to the changed function.
std::map<int, ChangedFunction> mChangedFunctions;
-
- const TString *const mReturnValueVariableName;
};
TIntermAggregate *ArrayReturnValueToOutParameterTraverser::createReplacementCall(
@@ -90,9 +90,7 @@
ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser(
TSymbolTable *symbolTable)
- : TIntermTraverser(true, false, true, symbolTable),
- mFunctionWithArrayReturnValue(nullptr),
- mReturnValueVariableName(NewPoolTString("angle_return"))
+ : TIntermTraverser(true, false, true, symbolTable), mFunctionWithArrayReturnValue(nullptr)
{
}
@@ -126,9 +124,9 @@
returnValueVariableType->setQualifier(EvqOut);
ChangedFunction changedFunction;
changedFunction.returnValueVariable =
- new TVariable(mSymbolTable, mReturnValueVariableName, returnValueVariableType,
+ new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType,
SymbolType::AngleInternal);
- TFunction *func = new TFunction(mSymbolTable, &node->getFunction()->name(),
+ TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(),
StaticType::GetBasic<EbtVoid>(),
node->getFunction()->symbolType(), false);
for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
@@ -136,7 +134,7 @@
func->addParameter(node->getFunction()->getParam(i));
}
func->addParameter(TConstParameter(
- mReturnValueVariableName, static_cast<const TType *>(returnValueVariableType)));
+ kReturnValueVariableName, static_cast<const TType *>(returnValueVariableType)));
changedFunction.func = func;
mChangedFunctions[functionId.get()] = changedFunction;
}
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index 3dc8846..e8a6fd8 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -10,8 +10,9 @@
#include <algorithm>
#include <array>
-#include "common/debug.h"
#include "GLSLANG/ShaderLang.h"
+#include "common/debug.h"
+#include "compiler/translator/ImmutableString.h"
namespace sh
{
@@ -1054,7 +1055,7 @@
}
}
-inline TYuvCscStandardEXT getYuvCscStandardEXT(const std::string &str)
+inline TYuvCscStandardEXT getYuvCscStandardEXT(const ImmutableString &str)
{
if (str == "itu_601")
return EycsItu601;
diff --git a/src/compiler/translator/CallDAG.cpp b/src/compiler/translator/CallDAG.cpp
index fc61d96..a931ed1 100644
--- a/src/compiler/translator/CallDAG.cpp
+++ b/src/compiler/translator/CallDAG.cpp
@@ -88,17 +88,13 @@
struct CreatorFunctionData
{
CreatorFunctionData()
- : definitionNode(nullptr),
- name(nullptr),
- index(0),
- indexAssigned(false),
- visiting(false)
+ : definitionNode(nullptr), name(""), index(0), indexAssigned(false), visiting(false)
{
}
std::set<CreatorFunctionData *> callees;
TIntermFunctionDefinition *definitionNode;
- const TString *name;
+ ImmutableString name;
size_t index;
bool indexAssigned;
bool visiting;
@@ -110,9 +106,9 @@
mCurrentFunction = &mFunctions[node->getFunction()->uniqueId().get()];
// Name will be overwritten here. If we've already traversed the prototype of this function,
// it should have had the same name.
- ASSERT(mCurrentFunction->name == nullptr ||
- *mCurrentFunction->name == node->getFunction()->name());
- mCurrentFunction->name = &node->getFunction()->name();
+ ASSERT(mCurrentFunction->name == "" ||
+ mCurrentFunction->name == node->getFunction()->name());
+ mCurrentFunction->name = node->getFunction()->name();
mCurrentFunction->definitionNode = node;
node->getBody()->traverse(this);
@@ -126,7 +122,7 @@
// Function declaration, create an empty record.
auto &record = mFunctions[node->getFunction()->uniqueId().get()];
- record.name = &node->getFunction()->name();
+ record.name = node->getFunction()->name();
// No need to traverse the parameters.
return false;
@@ -198,7 +194,7 @@
if (!function->definitionNode)
{
- errorStream << "Undefined function '" << *function->name
+ errorStream << "Undefined function '" << function->name
<< ")' used in the following call chain:";
result = INITDAG_UNDEFINED;
break;
@@ -244,7 +240,7 @@
{
errorStream << " -> ";
}
- errorStream << *function->name << ")";
+ errorStream << function->name << ")";
first = false;
}
}
diff --git a/src/compiler/translator/ClampFragDepth.cpp b/src/compiler/translator/ClampFragDepth.cpp
index 70852aa..448c9c0 100644
--- a/src/compiler/translator/ClampFragDepth.cpp
+++ b/src/compiler/translator/ClampFragDepth.cpp
@@ -11,6 +11,7 @@
#include "compiler/translator/ClampFragDepth.h"
#include "compiler/translator/FindSymbolNode.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/RunAtTheEndOfShader.h"
#include "compiler/translator/SymbolTable.h"
@@ -21,12 +22,13 @@
void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable)
{
// Only clamp gl_FragDepth if it's used in the shader.
- if (!FindSymbolNode(root, TString("gl_FragDepth")))
+ if (!FindSymbolNode(root, ImmutableString("gl_FragDepth")))
{
return;
}
- TIntermSymbol *fragDepthNode = ReferenceBuiltInVariable("gl_FragDepth", *symbolTable, 300);
+ TIntermSymbol *fragDepthNode =
+ ReferenceBuiltInVariable(ImmutableString("gl_FragDepth"), *symbolTable, 300);
TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
diff --git a/src/compiler/translator/ClampPointSize.cpp b/src/compiler/translator/ClampPointSize.cpp
index b16a2f3..e6e9a0e 100644
--- a/src/compiler/translator/ClampPointSize.cpp
+++ b/src/compiler/translator/ClampPointSize.cpp
@@ -19,12 +19,13 @@
void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable)
{
// Only clamp gl_PointSize if it's used in the shader.
- if (!FindSymbolNode(root, TString("gl_PointSize")))
+ if (!FindSymbolNode(root, ImmutableString("gl_PointSize")))
{
return;
}
- TIntermSymbol *pointSizeNode = ReferenceBuiltInVariable("gl_PointSize", *symbolTable, 100);
+ TIntermSymbol *pointSizeNode =
+ ReferenceBuiltInVariable(ImmutableString("gl_PointSize"), *symbolTable, 100);
TConstantUnion *maxPointSizeConstant = new TConstantUnion();
maxPointSizeConstant->setFConst(maxPointSize);
diff --git a/src/compiler/translator/CollectVariables.cpp b/src/compiler/translator/CollectVariables.cpp
index 0b7cd70..e0f73ca 100644
--- a/src/compiler/translator/CollectVariables.cpp
+++ b/src/compiler/translator/CollectVariables.cpp
@@ -56,12 +56,12 @@
}
template <class VarT>
-VarT *FindVariable(const TString &name, std::vector<VarT> *infoList)
+VarT *FindVariable(const ImmutableString &name, std::vector<VarT> *infoList)
{
// TODO(zmo): optimize this function.
for (size_t ii = 0; ii < infoList->size(); ++ii)
{
- if ((*infoList)[ii].name.c_str() == name)
+ if (name == (*infoList)[ii].name)
return &((*infoList)[ii]);
}
@@ -86,7 +86,7 @@
}
}
-ShaderVariable *FindVariableInInterfaceBlock(const TString &name,
+ShaderVariable *FindVariableInInterfaceBlock(const ImmutableString &name,
const TInterfaceBlock *interfaceBlock,
std::vector<InterfaceBlock> *infoList)
{
@@ -127,7 +127,7 @@
void setFieldOrVariableProperties(const TType &type, ShaderVariable *variableOut) const;
void setFieldProperties(const TType &type,
- const TString &name,
+ const ImmutableString &name,
ShaderVariable *variableOut) const;
void setCommonVariableProperties(const TType &type,
const TVariable &variable,
@@ -141,15 +141,15 @@
InterfaceBlock *interfaceBlock) const;
Uniform recordUniform(const TIntermSymbol &variable) const;
- void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info);
+ void setBuiltInInfoFromSymbolTable(const ImmutableString &name, ShaderVariable *info);
- void recordBuiltInVaryingUsed(const char *name,
+ void recordBuiltInVaryingUsed(const ImmutableString &name,
bool *addedFlag,
std::vector<Varying> *varyings);
- void recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag);
- void recordBuiltInAttributeUsed(const char *name, bool *addedFlag);
+ void recordBuiltInFragmentOutputUsed(const ImmutableString &name, bool *addedFlag);
+ void recordBuiltInAttributeUsed(const ImmutableString &name, bool *addedFlag);
InterfaceBlock *recordGLInUsed(const TType &glInType);
- InterfaceBlock *findNamedInterfaceBlock(const TString &name) const;
+ InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
std::vector<Attribute> *mAttribs;
std::vector<OutputVariable> *mOutputVariables;
@@ -253,10 +253,10 @@
std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
{
- return HashName(symbol, mHashFunction, nullptr).c_str();
+ return HashName(symbol, mHashFunction, nullptr).data();
}
-void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
+void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const ImmutableString &name,
ShaderVariable *info)
{
const TVariable *symbolTableVar =
@@ -264,8 +264,8 @@
ASSERT(symbolTableVar);
const TType &type = symbolTableVar->getType();
- info->name = name;
- info->mappedName = name;
+ info->name = name.data();
+ info->mappedName = name.data();
info->type = GLVariableType(type);
info->precision = GLVariablePrecision(type);
if (auto *arraySizes = type.getArraySizes())
@@ -274,7 +274,7 @@
}
}
-void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name,
+void CollectVariablesTraverser::recordBuiltInVaryingUsed(const ImmutableString &name,
bool *addedFlag,
std::vector<Varying> *varyings)
{
@@ -284,13 +284,14 @@
Varying info;
setBuiltInInfoFromSymbolTable(name, &info);
info.staticUse = true;
- info.isInvariant = mSymbolTable->isVaryingInvariant(name);
+ info.isInvariant = mSymbolTable->isVaryingInvariant(name.data());
varyings->push_back(info);
(*addedFlag) = true;
}
}
-void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag)
+void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const ImmutableString &name,
+ bool *addedFlag)
{
if (!(*addedFlag))
{
@@ -302,7 +303,8 @@
}
}
-void CollectVariablesTraverser::recordBuiltInAttributeUsed(const char *name, bool *addedFlag)
+void CollectVariablesTraverser::recordBuiltInAttributeUsed(const ImmutableString &name,
+ bool *addedFlag)
{
if (!(*addedFlag))
{
@@ -330,7 +332,7 @@
}
else
{
- return FindVariable("gl_PerVertex", mInBlocks);
+ return FindVariable(ImmutableString("gl_PerVertex"), mInBlocks);
}
}
@@ -352,7 +354,7 @@
ShaderVariable *var = nullptr;
- const TString &symbolName = symbol->getName();
+ const ImmutableString &symbolName = symbol->getName();
// Check the qualifier from the variable, not from the symbol node. The node may have a
// different qualifier if it's the result of a folded ternary node.
@@ -437,7 +439,7 @@
}
// It's an internal error to reference an undefined user uniform
- ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
+ ASSERT(!symbolName.beginsWith("gl_") || var);
}
break;
case EvqBuffer:
@@ -448,13 +450,16 @@
}
break;
case EvqFragCoord:
- recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_FragCoord"), &mFragCoordAdded,
+ mInputVaryings);
return;
case EvqFrontFacing:
- recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_FrontFacing"), &mFrontFacingAdded,
+ mInputVaryings);
return;
case EvqPointCoord:
- recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_PointCoord"), &mPointCoordAdded,
+ mInputVaryings);
return;
case EvqInstanceID:
// Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set,
@@ -477,25 +482,28 @@
}
return;
case EvqVertexID:
- recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded);
+ recordBuiltInAttributeUsed(ImmutableString("gl_VertexID"), &mVertexIDAdded);
return;
case EvqPosition:
- recordBuiltInVaryingUsed("gl_Position", &mPositionAdded, mOutputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_Position"), &mPositionAdded,
+ mOutputVaryings);
return;
case EvqPointSize:
- recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded, mOutputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_PointSize"), &mPointSizeAdded,
+ mOutputVaryings);
return;
case EvqLastFragData:
- recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_LastFragData"), &mLastFragDataAdded,
+ mInputVaryings);
return;
case EvqFragColor:
- recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded);
+ recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragColor"), &mFragColorAdded);
return;
case EvqFragData:
if (!mFragDataAdded)
{
OutputVariable info;
- setBuiltInInfoFromSymbolTable("gl_FragData", &info);
+ setBuiltInInfoFromSymbolTable(ImmutableString("gl_FragData"), &info);
if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
{
ASSERT(info.arraySizes.size() == 1u);
@@ -507,44 +515,51 @@
}
return;
case EvqFragDepthEXT:
- recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded);
+ recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragDepthEXT"),
+ &mFragDepthEXTAdded);
return;
case EvqFragDepth:
- recordBuiltInFragmentOutputUsed("gl_FragDepth", &mFragDepthAdded);
+ recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragDepth"), &mFragDepthAdded);
return;
case EvqSecondaryFragColorEXT:
- recordBuiltInFragmentOutputUsed("gl_SecondaryFragColorEXT",
+ recordBuiltInFragmentOutputUsed(ImmutableString("gl_SecondaryFragColorEXT"),
&mSecondaryFragColorEXTAdded);
return;
case EvqSecondaryFragDataEXT:
- recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT",
+ recordBuiltInFragmentOutputUsed(ImmutableString("gl_SecondaryFragDataEXT"),
&mSecondaryFragDataEXTAdded);
return;
case EvqInvocationID:
- recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_InvocationID"), &mInvocationIDAdded,
+ mInputVaryings);
break;
case EvqPrimitiveIDIn:
- recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveIDIn"), &mPrimitiveIDInAdded,
+ mInputVaryings);
break;
case EvqPrimitiveID:
if (mShaderType == GL_GEOMETRY_SHADER_EXT)
{
- recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveID"), &mPrimitiveIDAdded,
+ mOutputVaryings);
}
else
{
ASSERT(mShaderType == GL_FRAGMENT_SHADER);
- recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveID"), &mPrimitiveIDAdded,
+ mInputVaryings);
}
break;
case EvqLayer:
if (mShaderType == GL_GEOMETRY_SHADER_EXT)
{
- recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_Layer"), &mLayerAdded,
+ mOutputVaryings);
}
else if (mShaderType == GL_FRAGMENT_SHADER)
{
- recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings);
+ recordBuiltInVaryingUsed(ImmutableString("gl_Layer"), &mLayerAdded,
+ mInputVaryings);
}
else
{
@@ -579,7 +594,7 @@
variableOut->type = GL_NONE;
if (structure->symbolType() != SymbolType::Empty)
{
- variableOut->structName = structure->name().c_str();
+ variableOut->structName = structure->name().data();
}
const TFieldList &fields = structure->fields();
@@ -600,13 +615,13 @@
}
void CollectVariablesTraverser::setFieldProperties(const TType &type,
- const TString &name,
+ const ImmutableString &name,
ShaderVariable *variableOut) const
{
ASSERT(variableOut);
setFieldOrVariableProperties(type, variableOut);
- variableOut->name = name.c_str();
- variableOut->mappedName = HashName(name, mHashFunction, nullptr).c_str();
+ variableOut->name.assign(name.data(), name.length());
+ variableOut->mappedName = HashName(name, mHashFunction, nullptr).data();
}
void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
@@ -617,7 +632,7 @@
setFieldOrVariableProperties(type, variableOut);
ASSERT(variable.symbolType() != SymbolType::Empty);
- variableOut->name = variable.name().c_str();
+ variableOut->name.assign(variable.name().data(), variable.name().length());
variableOut->mappedName = getMappedName(&variable);
}
@@ -686,7 +701,7 @@
const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
ASSERT(blockType);
- interfaceBlock->name = blockType->name().c_str();
+ interfaceBlock->name = blockType->name().data();
interfaceBlock->mappedName = getMappedName(blockType);
if (instanceName != nullptr)
{
@@ -765,7 +780,7 @@
{
InterfaceBlock interfaceBlock;
recordInterfaceBlock(variable.variable().symbolType() != SymbolType::Empty
- ? variable.getName().c_str()
+ ? variable.getName().data()
: nullptr,
variable.getType(), &interfaceBlock);
@@ -818,7 +833,8 @@
// TODO(jiawei.shao@intel.com): add search on mInBlocks and mOutBlocks when implementing
// GL_EXT_shader_io_blocks.
-InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(const TString &blockName) const
+InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(
+ const ImmutableString &blockName) const
{
InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
if (!namedBlock)
diff --git a/src/compiler/translator/Common.h b/src/compiler/translator/Common.h
index e022194..b606e85 100644
--- a/src/compiler/translator/Common.h
+++ b/src/compiler/translator/Common.h
@@ -50,11 +50,6 @@
typedef pool_allocator<char> TStringAllocator;
typedef std::basic_string<char, std::char_traits<char>, TStringAllocator> TString;
typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
-inline TString *NewPoolTString(const char *s)
-{
- void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
- return new (memory) TString(s);
-}
//
// Persistent string memory. Should only be used for strings that survive
@@ -128,7 +123,7 @@
size_t requiredSize = strLength + 1;
char *buffer = reinterpret_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
memcpy(buffer, str, requiredSize);
- ASSERT(buffer[strLength] == 0);
+ ASSERT(buffer[strLength] == '\0');
return buffer;
}
diff --git a/src/compiler/translator/Declarator.cpp b/src/compiler/translator/Declarator.cpp
index 7ca0011..7a17a82 100644
--- a/src/compiler/translator/Declarator.cpp
+++ b/src/compiler/translator/Declarator.cpp
@@ -11,18 +11,17 @@
namespace sh
{
-TDeclarator::TDeclarator(const TString *name, const TSourceLoc &line)
+TDeclarator::TDeclarator(const ImmutableString &name, const TSourceLoc &line)
: mName(name), mArraySizes(nullptr), mLine(line)
{
- ASSERT(mName);
+ ASSERT(mName != "");
}
-TDeclarator::TDeclarator(const TString *name,
+TDeclarator::TDeclarator(const ImmutableString &name,
const TVector<unsigned int> *arraySizes,
const TSourceLoc &line)
: mName(name), mArraySizes(arraySizes), mLine(line)
{
- ASSERT(mName);
ASSERT(mArraySizes);
}
diff --git a/src/compiler/translator/Declarator.h b/src/compiler/translator/Declarator.h
index f013036..7801b65 100644
--- a/src/compiler/translator/Declarator.h
+++ b/src/compiler/translator/Declarator.h
@@ -10,6 +10,7 @@
#define COMPILER_TRANSLATOR_DECLARATOR_H_
#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
namespace sh
{
@@ -19,13 +20,13 @@
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TDeclarator(const TString *name, const TSourceLoc &line);
+ TDeclarator(const ImmutableString &name, const TSourceLoc &line);
- TDeclarator(const TString *name,
+ TDeclarator(const ImmutableString &name,
const TVector<unsigned int> *arraySizes,
const TSourceLoc &line);
- const TString *name() const { return mName; }
+ const ImmutableString &name() const { return mName; }
bool isArray() const;
const TVector<unsigned int> *arraySizes() const { return mArraySizes; }
@@ -33,7 +34,7 @@
const TSourceLoc &line() const { return mLine; }
private:
- const TString *const mName;
+ const ImmutableString mName;
// Outermost array size is stored at the end of the vector.
const TVector<unsigned int> *const mArraySizes;
diff --git a/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp b/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
index 837e4bc..5929577 100644
--- a/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
+++ b/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
@@ -24,9 +24,18 @@
namespace
{
+constexpr const ImmutableString kGlLayerString("gl_Layer");
+constexpr const ImmutableString kGlViewportIndexString("gl_ViewportIndex");
+constexpr const ImmutableString kGlViewIdOVRString("gl_ViewID_OVR");
+constexpr const ImmutableString kGlInstanceIdString("gl_InstanceID");
+constexpr const ImmutableString kViewIDVariableName("ViewID_OVR");
+constexpr const ImmutableString kInstanceIDVariableName("InstanceID");
+constexpr const ImmutableString kMultiviewBaseViewLayerIndexVariableName(
+ "multiviewBaseViewLayerIndex");
+
TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable)
{
- return ReferenceBuiltInVariable("gl_InstanceID", symbolTable, 300);
+ return ReferenceBuiltInVariable(kGlInstanceIdString, symbolTable, 300);
}
// Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence.
@@ -97,7 +106,7 @@
// Create a gl_ViewportIndex node.
TIntermSymbol *viewportIndexSymbol =
- ReferenceBuiltInVariable("gl_ViewportIndex", symbolTable, 0);
+ ReferenceBuiltInVariable(kGlViewportIndexString, symbolTable, 0);
// Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
@@ -105,7 +114,7 @@
new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt));
// Create a gl_Layer node.
- TIntermSymbol *layerSymbol = ReferenceBuiltInVariable("gl_Layer", symbolTable, 0);
+ TIntermSymbol *layerSymbol = ReferenceBuiltInVariable(kGlLayerString, symbolTable, 0);
// Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
TIntermBinary *sumOfViewIDAndBaseViewIndex = new TIntermBinary(
@@ -141,28 +150,28 @@
ASSERT(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER);
TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
- const TString *viewIDVariableName = NewPoolTString("ViewID_OVR");
const TVariable *viewID =
- new TVariable(symbolTable, viewIDVariableName, new TType(EbtUInt, EbpHigh, viewIDQualifier),
- SymbolType::AngleInternal);
+ new TVariable(symbolTable, kViewIDVariableName,
+ new TType(EbtUInt, EbpHigh, viewIDQualifier), SymbolType::AngleInternal);
DeclareGlobalVariable(root, viewID);
ReplaceVariable(
- root, static_cast<const TVariable *>(symbolTable->findBuiltIn("gl_ViewID_OVR", 300, true)),
+ root,
+ static_cast<const TVariable *>(symbolTable->findBuiltIn(kGlViewIdOVRString, 300, true)),
viewID);
if (shaderType == GL_VERTEX_SHADER)
{
// Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
// InstanceID and ViewID.
- const TString *instanceIDVariableName = NewPoolTString("InstanceID");
const TType *instanceIDVariableType = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
- const TVariable *instanceID = new TVariable(
- symbolTable, instanceIDVariableName, instanceIDVariableType, SymbolType::AngleInternal);
+ const TVariable *instanceID =
+ new TVariable(symbolTable, kInstanceIDVariableName, instanceIDVariableType,
+ SymbolType::AngleInternal);
DeclareGlobalVariable(root, instanceID);
- ReplaceVariable(
- root,
- static_cast<const TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
- instanceID);
+ ReplaceVariable(root,
+ static_cast<const TVariable *>(
+ symbolTable->findBuiltIn(kGlInstanceIdString, 300, true)),
+ instanceID);
TIntermSequence *initializers = new TIntermSequence();
InitializeViewIDAndInstanceID(viewID, instanceID, numberOfViews, *symbolTable,
@@ -177,12 +186,10 @@
if (selectView)
{
// Add a uniform to switch between side-by-side and layered rendering.
- const TString *multiviewBaseViewLayerIndexVariableName =
- NewPoolTString("multiviewBaseViewLayerIndex");
const TType *baseLayerIndexVariableType =
StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
const TVariable *multiviewBaseViewLayerIndex =
- new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName,
+ new TVariable(symbolTable, kMultiviewBaseViewLayerIndexVariableName,
baseLayerIndexVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index b4c742b..1704d41 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -30,6 +30,8 @@
namespace
{
+constexpr const ImmutableString kInitGlobalsString("initGlobals");
+
void GetDeferredInitializers(TIntermDeclaration *declaration,
bool initializeUninitializedGlobals,
bool canUseLoopsToInitialize,
@@ -102,9 +104,8 @@
TIntermBlock *initGlobalsBlock = new TIntermBlock();
initGlobalsBlock->getSequence()->swap(*deferredInitializers);
- TFunction *initGlobalsFunction =
- new TFunction(symbolTable, NewPoolTString("initGlobals"), new TType(EbtVoid),
- SymbolType::AngleInternal, false);
+ TFunction *initGlobalsFunction = new TFunction(
+ symbolTable, kInitGlobalsString, new TType(EbtVoid), SymbolType::AngleInternal, false);
TIntermFunctionPrototype *initGlobalsFunctionPrototype =
CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
@@ -156,7 +157,7 @@
TType *replacementType = new TType(var->getType());
replacementType->setQualifier(EvqGlobal);
TVariable *replacement =
- new TVariable(symbolTable, &var->name(), replacementType, var->symbolType());
+ new TVariable(symbolTable, var->name(), replacementType, var->symbolType());
ReplaceVariable(root, var, replacement);
}
}
diff --git a/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
index f1a8d8d..7689f04 100644
--- a/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ b/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
@@ -24,6 +24,8 @@
namespace
{
+constexpr const ImmutableString kGlFragDataString("gl_FragData");
+
class GLFragColorBroadcastTraverser : public TIntermTraverser
{
public:
@@ -54,7 +56,7 @@
TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
{
TIntermSymbol *symbol =
- ReferenceBuiltInVariable(TString("gl_FragData"), *mSymbolTable, mShaderVersion);
+ ReferenceBuiltInVariable(kGlFragDataString, *mSymbolTable, mShaderVersion);
TIntermTyped *indexNode = CreateIndexNode(index);
TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index da3ff5a..d3acfbd 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -16,6 +16,11 @@
namespace
{
+constexpr const ImmutableString kParamXName("x");
+constexpr const ImmutableString kParamYName("y");
+constexpr const ImmutableString kAngleFrmString("angle_frm");
+constexpr const ImmutableString kAngleFrlString("angle_frl");
+
class RoundingHelperWriter : angle::NonCopyable
{
public:
@@ -473,10 +478,7 @@
} // namespace anonymous
EmulatePrecision::EmulatePrecision(TSymbolTable *symbolTable)
- : TLValueTrackingTraverser(true, true, true, symbolTable),
- mDeclaringVariables(false),
- mParamXName(NewPoolTString("x")),
- mParamYName(NewPoolTString("y"))
+ : TLValueTrackingTraverser(true, true, true, symbolTable), mDeclaringVariables(false)
{
}
@@ -709,13 +711,13 @@
}
}
-const TFunction *EmulatePrecision::getInternalFunction(TString *functionName,
+const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &functionName,
const TType &returnType,
TIntermSequence *arguments,
const TVector<TConstParameter> ¶meters,
bool knownToNotHaveSideEffects)
{
- TString mangledName = TFunctionLookup::GetMangledName(*functionName, *arguments);
+ ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
{
TFunction *func = new TFunction(mSymbolTable, functionName, new TType(returnType),
@@ -732,12 +734,9 @@
TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
{
- const char *roundFunctionName;
- if (roundedChild->getPrecision() == EbpMedium)
- roundFunctionName = "angle_frm";
- else
- roundFunctionName = "angle_frl";
- TString *functionName = NewPoolTString(roundFunctionName);
+ const ImmutableString *roundFunctionName = &kAngleFrmString;
+ if (roundedChild->getPrecision() == EbpLow)
+ roundFunctionName = &kAngleFrlString;
TIntermSequence *arguments = new TIntermSequence();
arguments->push_back(roundedChild);
@@ -745,10 +744,11 @@
TType *paramType = new TType(roundedChild->getType());
paramType->setPrecision(EbpHigh);
paramType->setQualifier(EvqIn);
- parameters.push_back(TConstParameter(mParamXName, static_cast<const TType *>(paramType)));
+ parameters.push_back(TConstParameter(kParamXName, static_cast<const TType *>(paramType)));
return TIntermAggregate::CreateRawFunctionCall(
- *getInternalFunction(functionName, roundedChild->getType(), arguments, parameters, true),
+ *getInternalFunction(*roundFunctionName, roundedChild->getType(), arguments, parameters,
+ true),
arguments);
}
@@ -761,7 +761,7 @@
strstr << "angle_compound_" << opNameStr << "_frm";
else
strstr << "angle_compound_" << opNameStr << "_frl";
- TString *functionName = NewPoolTString(strstr.str().c_str());
+ ImmutableString functionName = ImmutableString(strstr.str());
TIntermSequence *arguments = new TIntermSequence();
arguments->push_back(left);
arguments->push_back(right);
@@ -770,11 +770,11 @@
TType *leftParamType = new TType(left->getType());
leftParamType->setPrecision(EbpHigh);
leftParamType->setQualifier(EvqOut);
- parameters.push_back(TConstParameter(mParamXName, static_cast<const TType *>(leftParamType)));
+ parameters.push_back(TConstParameter(kParamXName, static_cast<const TType *>(leftParamType)));
TType *rightParamType = new TType(right->getType());
rightParamType->setPrecision(EbpHigh);
rightParamType->setQualifier(EvqIn);
- parameters.push_back(TConstParameter(mParamYName, static_cast<const TType *>(rightParamType)));
+ parameters.push_back(TConstParameter(kParamYName, static_cast<const TType *>(rightParamType)));
return TIntermAggregate::CreateRawFunctionCall(
*getInternalFunction(functionName, left->getType(), arguments, parameters, false),
diff --git a/src/compiler/translator/EmulatePrecision.h b/src/compiler/translator/EmulatePrecision.h
index c8eadc1..5010882 100644
--- a/src/compiler/translator/EmulatePrecision.h
+++ b/src/compiler/translator/EmulatePrecision.h
@@ -59,7 +59,7 @@
}
};
- const TFunction *getInternalFunction(TString *functionName,
+ const TFunction *getInternalFunction(const ImmutableString &functionName,
const TType &returnType,
TIntermSequence *arguments,
const TVector<TConstParameter> ¶meters,
@@ -76,12 +76,9 @@
EmulationSet mEmulateCompoundDiv;
// Map from mangled name to function.
- TMap<TString, const TFunction *> mInternalFunctions;
+ TMap<ImmutableString, const TFunction *> mInternalFunctions;
bool mDeclaringVariables;
-
- const TString *mParamXName;
- const TString *mParamYName;
};
} // namespace sh
diff --git a/src/compiler/translator/FindSymbolNode.cpp b/src/compiler/translator/FindSymbolNode.cpp
index a1e5634..f63acf5 100644
--- a/src/compiler/translator/FindSymbolNode.cpp
+++ b/src/compiler/translator/FindSymbolNode.cpp
@@ -8,6 +8,7 @@
#include "compiler/translator/FindSymbolNode.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/Symbol.h"
@@ -20,7 +21,7 @@
class SymbolFinder : public TIntermTraverser
{
public:
- SymbolFinder(const TString &symbolName)
+ SymbolFinder(const ImmutableString &symbolName)
: TIntermTraverser(true, false, false), mSymbolName(symbolName), mNodeFound(nullptr)
{
}
@@ -37,13 +38,13 @@
const TIntermSymbol *getNode() const { return mNodeFound; }
private:
- TString mSymbolName;
+ ImmutableString mSymbolName;
TIntermSymbol *mNodeFound;
};
} // anonymous namespace
-const TIntermSymbol *FindSymbolNode(TIntermNode *root, const TString &symbolName)
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName)
{
SymbolFinder finder(symbolName);
root->traverse(&finder);
diff --git a/src/compiler/translator/FindSymbolNode.h b/src/compiler/translator/FindSymbolNode.h
index 7f65449..0e6f8cb 100644
--- a/src/compiler/translator/FindSymbolNode.h
+++ b/src/compiler/translator/FindSymbolNode.h
@@ -9,16 +9,14 @@
#ifndef COMPILER_TRANSLATOR_FIND_SYMBOL_H_
#define COMPILER_TRANSLATOR_FIND_SYMBOL_H_
-#include "compiler/translator/BaseTypes.h"
-#include "compiler/translator/Common.h"
-
namespace sh
{
+class ImmutableString;
class TIntermNode;
class TIntermSymbol;
-const TIntermSymbol *FindSymbolNode(TIntermNode *root, const TString &symbolName);
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName);
} // namespace sh
diff --git a/src/compiler/translator/FunctionLookup.cpp b/src/compiler/translator/FunctionLookup.cpp
index ee575a8..1a81f9a 100644
--- a/src/compiler/translator/FunctionLookup.cpp
+++ b/src/compiler/translator/FunctionLookup.cpp
@@ -17,9 +17,11 @@
const char kFunctionMangledNameSeparator = '(';
+constexpr const ImmutableString kEmptyName("");
+
} // anonymous namespace
-TFunctionLookup::TFunctionLookup(const TString *name, const TType *constructorType)
+TFunctionLookup::TFunctionLookup(const ImmutableString &name, const TType *constructorType)
: mName(name), mConstructorType(constructorType), mThisNode(nullptr)
{
}
@@ -28,37 +30,37 @@
TFunctionLookup *TFunctionLookup::CreateConstructor(const TType *type)
{
ASSERT(type != nullptr);
- return new TFunctionLookup(nullptr, type);
+ return new TFunctionLookup(kEmptyName, type);
}
// static
-TFunctionLookup *TFunctionLookup::CreateFunctionCall(const TString *name)
+TFunctionLookup *TFunctionLookup::CreateFunctionCall(const ImmutableString &name)
{
- ASSERT(name != nullptr);
+ ASSERT(name != "");
return new TFunctionLookup(name, nullptr);
}
-const TString &TFunctionLookup::name() const
+const ImmutableString &TFunctionLookup::name() const
{
- return *mName;
+ return mName;
}
-const TString &TFunctionLookup::getMangledName() const
+ImmutableString TFunctionLookup::getMangledName() const
{
- return GetMangledName(*mName, mArguments);
+ return GetMangledName(mName.data(), mArguments);
}
-const TString &TFunctionLookup::GetMangledName(const TString &functionName,
- const TIntermSequence &arguments)
+ImmutableString TFunctionLookup::GetMangledName(const char *functionName,
+ const TIntermSequence &arguments)
{
- std::string newName = functionName.c_str();
+ std::string newName(functionName);
newName += kFunctionMangledNameSeparator;
for (TIntermNode *argument : arguments)
{
newName += argument->getAsTyped()->getType().getMangledName();
}
- return *NewPoolTString(newName.c_str());
+ return ImmutableString(newName);
}
bool TFunctionLookup::isConstructor() const
diff --git a/src/compiler/translator/FunctionLookup.h b/src/compiler/translator/FunctionLookup.h
index 1a62357..ed14822 100644
--- a/src/compiler/translator/FunctionLookup.h
+++ b/src/compiler/translator/FunctionLookup.h
@@ -9,6 +9,7 @@
#ifndef COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
#define COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode.h"
namespace sh
@@ -21,12 +22,12 @@
POOL_ALLOCATOR_NEW_DELETE();
static TFunctionLookup *CreateConstructor(const TType *type);
- static TFunctionLookup *CreateFunctionCall(const TString *name);
+ static TFunctionLookup *CreateFunctionCall(const ImmutableString &name);
- const TString &name() const;
- const TString &getMangledName() const;
- static const TString &GetMangledName(const TString &functionName,
- const TIntermSequence &arguments);
+ const ImmutableString &name() const;
+ ImmutableString getMangledName() const;
+ static ImmutableString GetMangledName(const char *functionName,
+ const TIntermSequence &arguments);
bool isConstructor() const;
const TType &constructorType() const;
@@ -38,9 +39,9 @@
TIntermSequence &arguments();
private:
- TFunctionLookup(const TString *name, const TType *constructorType);
+ TFunctionLookup(const ImmutableString &name, const TType *constructorType);
- const TString *mName;
+ const ImmutableString mName;
const TType *const mConstructorType;
TIntermTyped *mThisNode;
TIntermSequence mArguments;
diff --git a/src/compiler/translator/HashNames.cpp b/src/compiler/translator/HashNames.cpp
index df448d8..6f7a419 100644
--- a/src/compiler/translator/HashNames.cpp
+++ b/src/compiler/translator/HashNames.cpp
@@ -6,6 +6,8 @@
#include "compiler/translator/HashNames.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/Symbol.h"
@@ -18,59 +20,72 @@
// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
static const unsigned int kESSLMaxIdentifierLength = 1024u;
-static const char *kHashedNamePrefix = "webgl_";
+constexpr const ImmutableString kHashedNamePrefix("webgl_");
// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
// use by the underlying implementation). u is short for user-defined.
-static const char *kUnhashedNamePrefix = "_u";
-static const unsigned int kUnhashedNamePrefixLength = 2u;
+constexpr const ImmutableString kUnhashedNamePrefix("_u");
-TString HashName(const TString &name, ShHashFunction64 hashFunction)
+ImmutableString HashName(const ImmutableString &name, ShHashFunction64 hashFunction)
{
ASSERT(!name.empty());
ASSERT(hashFunction);
- khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
- TStringStream stream;
- stream << kHashedNamePrefix << std::hex << number;
- TString hashedName = stream.str();
+ khronos_uint64_t number = (*hashFunction)(name.data(), name.length());
+
+ // Build the hashed name in place.
+ static const unsigned int kHexStrMaxLength = sizeof(number) * 2;
+ static const size_t kHashedNameMaxLength = kHashedNamePrefix.length() + kHexStrMaxLength;
+
+ ImmutableStringBuilder hashedName(kHashedNameMaxLength);
+ hashedName << kHashedNamePrefix;
+
+ hashedName.appendHex(number);
+
return hashedName;
}
} // anonymous namespace
-TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap)
+ImmutableString HashName(const ImmutableString &name,
+ ShHashFunction64 hashFunction,
+ NameMap *nameMap)
{
if (hashFunction == nullptr)
{
- if (name.length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength)
+ if (name.length() + kUnhashedNamePrefix.length() > kESSLMaxIdentifierLength)
{
// If the identifier length is already close to the limit, we can't prefix it. This is
// not a problem since there are no builtins or ANGLE's internal variables that would
// have as long names and could conflict.
return name;
}
- return kUnhashedNamePrefix + name;
+ ImmutableStringBuilder prefixedName(kUnhashedNamePrefix.length() + name.length());
+ prefixedName << kUnhashedNamePrefix << name;
+ return prefixedName;
}
if (nameMap)
{
- NameMap::const_iterator it = nameMap->find(name.c_str());
+ NameMap::const_iterator it = nameMap->find(name.data());
if (it != nameMap->end())
- return it->second.c_str();
+ {
+ // TODO(oetuaho): Would be nice if we didn't need to allocate a string here.
+ return ImmutableString(it->second);
+ }
}
- TString hashedName = HashName(name, hashFunction);
+ ImmutableString hashedName = HashName(name, hashFunction);
if (nameMap)
{
- (*nameMap)[name.c_str()] = hashedName.c_str();
+ (*nameMap)[name.data()] = hashedName.data();
}
return hashedName;
}
-TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
+ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
{
if (symbol->symbolType() == SymbolType::Empty)
{
- return TString();
+ return ImmutableString("");
}
if (symbol->symbolType() == SymbolType::AngleInternal ||
symbol->symbolType() == SymbolType::BuiltIn)
diff --git a/src/compiler/translator/HashNames.h b/src/compiler/translator/HashNames.h
index 549dab3..132cb59 100644
--- a/src/compiler/translator/HashNames.h
+++ b/src/compiler/translator/HashNames.h
@@ -17,13 +17,16 @@
typedef std::map<TPersistString, TPersistString> NameMap;
+class ImmutableString;
class TSymbol;
-TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap);
+ImmutableString HashName(const ImmutableString &name,
+ ShHashFunction64 hashFunction,
+ NameMap *nameMap);
// Hash user-defined name for GLSL output, with special handling for internal names.
// The nameMap parameter is optional and is used to cache hashed names if set.
-TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap);
+ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap);
} // namespace sh
diff --git a/src/compiler/translator/ImageFunctionHLSL.cpp b/src/compiler/translator/ImageFunctionHLSL.cpp
index 40b5e1f..b3c3931 100644
--- a/src/compiler/translator/ImageFunctionHLSL.cpp
+++ b/src/compiler/translator/ImageFunctionHLSL.cpp
@@ -239,7 +239,7 @@
std::tie(rhs.image, rhs.imageInternalFormat, rhs.readonly, rhs.method);
}
-TString ImageFunctionHLSL::useImageFunction(const TString &name,
+TString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
const TBasicType &type,
TLayoutImageInternalFormat imageInternalFormat,
bool readonly)
diff --git a/src/compiler/translator/ImageFunctionHLSL.h b/src/compiler/translator/ImageFunctionHLSL.h
index 9db17a6..4ff0110 100644
--- a/src/compiler/translator/ImageFunctionHLSL.h
+++ b/src/compiler/translator/ImageFunctionHLSL.h
@@ -25,7 +25,7 @@
public:
// Returns the name of the image function implementation to caller.
// The name that's passed in is the name of the GLSL image function that it should implement.
- TString useImageFunction(const TString &name,
+ TString useImageFunction(const ImmutableString &name,
const TBasicType &type,
TLayoutImageInternalFormat imageInternalFormat,
bool readonly);
diff --git a/src/compiler/translator/ImmutableString.cpp b/src/compiler/translator/ImmutableString.cpp
index 93dad1b..6bb26af 100644
--- a/src/compiler/translator/ImmutableString.cpp
+++ b/src/compiler/translator/ImmutableString.cpp
@@ -13,3 +13,26 @@
{
return os.write(str.data(), str.length());
}
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4309) // truncation of constant value
+#endif
+
+namespace sh
+{
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
+ static_cast<size_t>(1099511628211ull);
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
+ static_cast<size_t>(0xcbf29ce484222325ull);
+
+} // namespace sh
diff --git a/src/compiler/translator/ImmutableString.h b/src/compiler/translator/ImmutableString.h
index a33fec9..2caef8d 100644
--- a/src/compiler/translator/ImmutableString.h
+++ b/src/compiler/translator/ImmutableString.h
@@ -12,6 +12,7 @@
#include <string>
+#include "common/string_utils.h"
#include "compiler/translator/Common.h"
namespace sh
@@ -40,20 +41,60 @@
// The data pointer passed in must be one of:
// 1. nullptr (only valid with length 0).
// 2. a null-terminated static char array like a string literal.
- // 3. a null-terminated pool allocated char array.
+ // 3. a null-terminated pool allocated char array. This can't be c_str() of a local TString,
+ // since when a TString goes out of scope it clears its first character.
explicit constexpr ImmutableString(const char *data) : mData(data), mLength(constStrlen(data))
{
}
constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
+ ImmutableString(const std::string &str)
+ : mData(AllocatePoolCharArray(str.c_str(), str.size())), mLength(str.size())
+ {
+ }
+
ImmutableString(const ImmutableString &) = default;
ImmutableString &operator=(const ImmutableString &) = default;
- const char *data() const { return mData ? mData : ""; }
- size_t length() const { return mLength; }
+ constexpr const char *data() const { return mData ? mData : ""; }
+ constexpr size_t length() const { return mLength; }
- bool operator<(const ImmutableString &b) const
+ char operator[](size_t index) const { return data()[index]; }
+
+ constexpr bool empty() const { return mLength == 0; }
+ bool beginsWith(const char *prefix) const { return angle::BeginsWith(data(), prefix); }
+ constexpr bool beginsWith(const ImmutableString &prefix) const
+ {
+ return mLength >= prefix.length() && memcmp(data(), prefix.data(), prefix.length()) == 0;
+ }
+ bool contains(const char *substr) const { return strstr(data(), substr) != nullptr; }
+
+ constexpr bool operator==(const ImmutableString &b) const
+ {
+ if (mLength != b.mLength)
+ {
+ return false;
+ }
+ return memcmp(data(), b.data(), mLength) == 0;
+ }
+ constexpr bool operator!=(const ImmutableString &b) const { return !(*this == b); }
+ constexpr bool operator==(const char *b) const
+ {
+ if (b == nullptr)
+ {
+ return empty();
+ }
+ return strcmp(data(), b) == 0;
+ }
+ constexpr bool operator!=(const char *b) const { return !(*this == b); }
+ bool operator==(const std::string &b) const
+ {
+ return mLength == b.length() && memcmp(data(), b.c_str(), mLength) == 0;
+ }
+ bool operator!=(const std::string &b) const { return !(*this == b); }
+
+ constexpr bool operator<(const ImmutableString &b) const
{
if (mLength < b.mLength)
{
@@ -66,6 +107,26 @@
return (memcmp(data(), b.data(), mLength) < 0);
}
+ template <size_t hashBytes>
+ struct FowlerNollVoHash
+ {
+ static const size_t kFnvOffsetBasis;
+ static const size_t kFnvPrime;
+
+ constexpr size_t operator()(const ImmutableString &a) const
+ {
+ const char *data = a.data();
+ size_t hash = kFnvOffsetBasis;
+ while ((*data) != '\0')
+ {
+ hash = hash ^ (*data);
+ hash = hash * kFnvPrime;
+ ++data;
+ }
+ return hash;
+ }
+ };
+
private:
const char *mData;
size_t mLength;
diff --git a/src/compiler/translator/ImmutableStringBuilder.h b/src/compiler/translator/ImmutableStringBuilder.h
index 94dcc3b..5580f20 100644
--- a/src/compiler/translator/ImmutableStringBuilder.h
+++ b/src/compiler/translator/ImmutableStringBuilder.h
@@ -32,6 +32,28 @@
// This invalidates the ImmutableStringBuilder, so it should only be called once.
operator ImmutableString();
+ template <typename T>
+ void appendHex(T number)
+ {
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + sizeof(T) * 2u <= mMaxLength);
+ int index = static_cast<int>(sizeof(T)) * 2 - 1;
+ // Loop through leading zeroes.
+ while (((number >> (index * 4)) & 0xfu) == 0 && index > 0)
+ {
+ --index;
+ }
+ // Write the rest of the hex digits.
+ while (index >= 0)
+ {
+ char digit = static_cast<char>((number >> (index * 4)) & 0xfu);
+ char digitChar = digit < 10 ? digit + '0' : digit + 'a';
+ mData[mPos++] = digitChar;
+ --index;
+ }
+ return;
+ }
+
private:
inline static char *AllocateEmptyPoolCharArray(size_t strLength)
{
diff --git a/src/compiler/translator/InfoSink.h b/src/compiler/translator/InfoSink.h
index 3f54f4a..ce326ce 100644
--- a/src/compiler/translator/InfoSink.h
+++ b/src/compiler/translator/InfoSink.h
@@ -24,6 +24,8 @@
return modff(f, &intPart);
}
+class ImmutableString;
+
//
// Encapsulate info logs for all objects that have them.
//
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index 91c5d07..0afcf4c 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -748,133 +748,161 @@
TFieldList *fields = new TFieldList();
TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
auto highpFloat1 = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
- TField *near = new TField(highpFloat1, NewPoolTString("near"), zeroSourceLoc);
- TField *far = new TField(highpFloat1, NewPoolTString("far"), zeroSourceLoc);
- TField *diff = new TField(highpFloat1, NewPoolTString("diff"), zeroSourceLoc);
+ TField *near = new TField(highpFloat1, ImmutableString("near"), zeroSourceLoc);
+ TField *far = new TField(highpFloat1, ImmutableString("far"), zeroSourceLoc);
+ TField *diff = new TField(highpFloat1, ImmutableString("diff"), zeroSourceLoc);
fields->push_back(near);
fields->push_back(far);
fields->push_back(diff);
TStructure *depthRangeStruct = new TStructure(
- &symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
+ &symbolTable, ImmutableString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct);
TType *depthRangeType = new TType(depthRangeStruct);
depthRangeType->setQualifier(EvqUniform);
depthRangeType->realize();
- symbolTable.insertVariable(COMMON_BUILTINS, "gl_DepthRange", depthRangeType);
+ symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_DepthRange"), depthRangeType);
//
// Implementation dependent built-in constants.
//
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexAttribs",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexAttribs"),
resources.MaxVertexAttribs);
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexUniformVectors",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
+ ImmutableString("gl_MaxVertexUniformVectors"),
resources.MaxVertexUniformVectors);
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
+ ImmutableString("gl_MaxVertexTextureImageUnits"),
resources.MaxVertexTextureImageUnits);
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
+ ImmutableString("gl_MaxCombinedTextureImageUnits"),
resources.MaxCombinedTextureImageUnits);
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxTextureImageUnits",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
+ ImmutableString("gl_MaxTextureImageUnits"),
resources.MaxTextureImageUnits);
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
+ ImmutableString("gl_MaxFragmentUniformVectors"),
resources.MaxFragmentUniformVectors);
- symbolTable.insertConstInt<EbpMedium>(ESSL1_BUILTINS, "gl_MaxVaryingVectors",
+ symbolTable.insertConstInt<EbpMedium>(ESSL1_BUILTINS, ImmutableString("gl_MaxVaryingVectors"),
resources.MaxVaryingVectors);
- symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxDrawBuffers",
+ symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxDrawBuffers"),
resources.MaxDrawBuffers);
if (resources.EXT_blend_func_extended)
{
symbolTable.insertConstIntExt<EbpMedium>(
- COMMON_BUILTINS, TExtension::EXT_blend_func_extended, "gl_MaxDualSourceDrawBuffersEXT",
- resources.MaxDualSourceDrawBuffers);
+ COMMON_BUILTINS, TExtension::EXT_blend_func_extended,
+ ImmutableString("gl_MaxDualSourceDrawBuffersEXT"), resources.MaxDualSourceDrawBuffers);
}
- symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
+ ImmutableString("gl_MaxVertexOutputVectors"),
resources.MaxVertexOutputVectors);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
+ ImmutableString("gl_MaxFragmentInputVectors"),
resources.MaxFragmentInputVectors);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MinProgramTexelOffset",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
+ ImmutableString("gl_MinProgramTexelOffset"),
resources.MinProgramTexelOffset);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
+ ImmutableString("gl_MaxProgramTexelOffset"),
resources.MaxProgramTexelOffset);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxImageUnits",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxImageUnits"),
resources.MaxImageUnits);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxVertexImageUniforms"),
resources.MaxVertexImageUniforms);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxFragmentImageUniforms"),
resources.MaxFragmentImageUniforms);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeImageUniforms"),
resources.MaxComputeImageUniforms);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxCombinedImageUniforms"),
resources.MaxCombinedImageUniforms);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxCombinedShaderOutputResources"),
resources.MaxCombinedShaderOutputResources);
- symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount",
+ symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeWorkGroupCount"),
resources.MaxComputeWorkGroupCount);
- symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize",
+ symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeWorkGroupSize"),
resources.MaxComputeWorkGroupSize);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeUniformComponents"),
resources.MaxComputeUniformComponents);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeTextureImageUnits"),
resources.MaxComputeTextureImageUnits);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeAtomicCounters"),
resources.MaxComputeAtomicCounters);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxComputeAtomicCounterBuffers"),
resources.MaxComputeAtomicCounterBuffers);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxVertexAtomicCounters"),
resources.MaxVertexAtomicCounters);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxFragmentAtomicCounters"),
resources.MaxFragmentAtomicCounters);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxCombinedAtomicCounters"),
resources.MaxCombinedAtomicCounters);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxAtomicCounterBindings"),
resources.MaxAtomicCounterBindings);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxVertexAtomicCounterBuffers"),
resources.MaxVertexAtomicCounterBuffers);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxFragmentAtomicCounterBuffers"),
resources.MaxFragmentAtomicCounterBuffers);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxCombinedAtomicCounterBuffers"),
resources.MaxCombinedAtomicCounterBuffers);
- symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
+ symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+ ImmutableString("gl_MaxAtomicCounterBufferSize"),
resources.MaxAtomicCounterBufferSize);
if (resources.EXT_geometry_shader)
{
TExtension ext = TExtension::EXT_geometry_shader;
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryInputComponents",
+ ImmutableString("gl_MaxGeometryInputComponents"),
resources.MaxGeometryInputComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryOutputComponents",
+ ImmutableString("gl_MaxGeometryOutputComponents"),
resources.MaxGeometryOutputComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryImageUniforms",
+ ImmutableString("gl_MaxGeometryImageUniforms"),
resources.MaxGeometryImageUniforms);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryTextureImageUnits",
+ ImmutableString("gl_MaxGeometryTextureImageUnits"),
resources.MaxGeometryTextureImageUnits);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryOutputVertices",
+ ImmutableString("gl_MaxGeometryOutputVertices"),
resources.MaxGeometryOutputVertices);
+ symbolTable.insertConstIntExt<EbpMedium>(
+ ESSL3_1_BUILTINS, ext, ImmutableString("gl_MaxGeometryTotalOutputComponents"),
+ resources.MaxGeometryTotalOutputComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryTotalOutputComponents",
- resources.MaxGeometryTotalOutputComponents);
- symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryUniformComponents",
+ ImmutableString("gl_MaxGeometryUniformComponents"),
resources.MaxGeometryUniformComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryAtomicCounters",
+ ImmutableString("gl_MaxGeometryAtomicCounters"),
resources.MaxGeometryAtomicCounters);
- symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
- "gl_MaxGeometryAtomicCounterBuffers",
- resources.MaxGeometryAtomicCounterBuffers);
+ symbolTable.insertConstIntExt<EbpMedium>(
+ ESSL3_1_BUILTINS, ext, ImmutableString("gl_MaxGeometryAtomicCounterBuffers"),
+ resources.MaxGeometryAtomicCounterBuffers);
}
}
@@ -891,14 +919,14 @@
if (resources.OVR_multiview && type != GL_COMPUTE_SHADER)
{
const TType *viewIDType = StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>();
- symbolTable.insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR",
- viewIDType);
+ symbolTable.insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview,
+ ImmutableString("gl_ViewID_OVR"), viewIDType);
// ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL
// 1.00. This is specified in the WEBGL_multiview spec.
const TType *viewIDIntType = StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>();
- symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR",
- viewIDIntType);
+ symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview,
+ ImmutableString("gl_ViewID_OVR"), viewIDIntType);
}
const TType *positionType = StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>();
@@ -910,15 +938,19 @@
case GL_FRAGMENT_SHADER:
{
const TType *fragCoordType = StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>();
- symbolTable.insertVariable(COMMON_BUILTINS, "gl_FragCoord", fragCoordType);
+ symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_FragCoord"),
+ fragCoordType);
const TType *frontFacingType = StaticType::GetQualified<EbtBool, EvqFrontFacing>();
- symbolTable.insertVariable(COMMON_BUILTINS, "gl_FrontFacing", frontFacingType);
+ symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_FrontFacing"),
+ frontFacingType);
const TType *pointCoordType =
StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>();
- symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointCoord", pointCoordType);
+ symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointCoord"),
+ pointCoordType);
const TType *fragColorType = StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>();
- symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragColor", fragColorType);
+ symbolTable.insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragColor"),
+ fragColorType);
TType *fragDataType = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
@@ -930,20 +962,23 @@
fragDataType->makeArray(1u);
}
fragDataType->realize();
- symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragData", fragDataType);
+ symbolTable.insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragData"),
+ fragDataType);
if (resources.EXT_blend_func_extended)
{
const TType *secondaryFragColorType =
StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
- "gl_SecondaryFragColorEXT", secondaryFragColorType);
+ ImmutableString("gl_SecondaryFragColorEXT"),
+ secondaryFragColorType);
TType *secondaryFragDataType =
new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
secondaryFragDataType->makeArray(resources.MaxDualSourceDrawBuffers);
secondaryFragDataType->realize();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
- "gl_SecondaryFragDataEXT", secondaryFragDataType);
+ ImmutableString("gl_SecondaryFragDataEXT"),
+ secondaryFragDataType);
}
if (resources.EXT_frag_depth)
@@ -953,11 +988,12 @@
EvqFragDepthEXT, 1);
fragDepthEXTType->realize();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_frag_depth,
- "gl_FragDepthEXT", fragDepthEXTType);
+ ImmutableString("gl_FragDepthEXT"), fragDepthEXTType);
}
const TType *fragDepthType = StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>();
- symbolTable.insertVariable(ESSL3_BUILTINS, "gl_FragDepth", fragDepthType);
+ symbolTable.insertVariable(ESSL3_BUILTINS, ImmutableString("gl_FragDepth"),
+ fragDepthType);
const TType *lastFragColorType =
StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>();
@@ -970,77 +1006,86 @@
if (resources.EXT_shader_framebuffer_fetch)
{
- symbolTable.insertVariableExt(ESSL1_BUILTINS,
- TExtension::EXT_shader_framebuffer_fetch,
- "gl_LastFragData", lastFragDataType);
+ symbolTable.insertVariableExt(
+ ESSL1_BUILTINS, TExtension::EXT_shader_framebuffer_fetch,
+ ImmutableString("gl_LastFragData"), lastFragDataType);
}
else if (resources.NV_shader_framebuffer_fetch)
{
- symbolTable.insertVariableExt(ESSL1_BUILTINS,
- TExtension::NV_shader_framebuffer_fetch,
- "gl_LastFragColor", lastFragColorType);
- symbolTable.insertVariableExt(ESSL1_BUILTINS,
- TExtension::NV_shader_framebuffer_fetch,
- "gl_LastFragData", lastFragDataType);
+ symbolTable.insertVariableExt(
+ ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
+ ImmutableString("gl_LastFragColor"), lastFragColorType);
+ symbolTable.insertVariableExt(
+ ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
+ ImmutableString("gl_LastFragData"), lastFragDataType);
}
}
else if (resources.ARM_shader_framebuffer_fetch)
{
- symbolTable.insertVariableExt(ESSL1_BUILTINS,
- TExtension::ARM_shader_framebuffer_fetch,
- "gl_LastFragColorARM", lastFragColorType);
+ symbolTable.insertVariableExt(
+ ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch,
+ ImmutableString("gl_LastFragColorARM"), lastFragColorType);
}
if (resources.EXT_geometry_shader)
{
TExtension extension = TExtension::EXT_geometry_shader;
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
- primitiveIDType);
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", layerType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
+ ImmutableString("gl_PrimitiveID"), primitiveIDType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
+ ImmutableString("gl_Layer"), layerType);
}
break;
}
case GL_VERTEX_SHADER:
{
- symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position", positionType);
+ symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_Position"),
+ positionType);
const TType *pointSizeType = StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>();
- symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize", pointSizeType);
+ symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointSize"),
+ pointSizeType);
const TType *instanceIDType = StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>();
- symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID", instanceIDType);
+ symbolTable.insertVariable(ESSL3_BUILTINS, ImmutableString("gl_InstanceID"),
+ instanceIDType);
const TType *vertexIDType = StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>();
- symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID", vertexIDType);
+ symbolTable.insertVariable(ESSL3_BUILTINS, ImmutableString("gl_VertexID"),
+ vertexIDType);
// For internal use by ANGLE - not exposed to the parser.
const TType *viewportIndexType =
StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>();
- symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex", viewportIndexType);
+ symbolTable.insertVariable(GLSL_BUILTINS, ImmutableString("gl_ViewportIndex"),
+ viewportIndexType);
// gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
- symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", layerType);
+ symbolTable.insertVariable(GLSL_BUILTINS, ImmutableString("gl_Layer"), layerType);
break;
}
case GL_COMPUTE_SHADER:
{
const TType *numWorkGroupsType =
StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>();
- symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups", numWorkGroupsType);
+ symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_NumWorkGroups"),
+ numWorkGroupsType);
const TType *workGroupSizeType =
StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>();
- symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupSize", workGroupSizeType);
+ symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupSize"),
+ workGroupSizeType);
const TType *workGroupIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>();
- symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupID", workGroupIDType);
+ symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupID"),
+ workGroupIDType);
const TType *localInvocationIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>();
- symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationID",
+ symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationID"),
localInvocationIDType);
const TType *globalInvocationIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>();
- symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_GlobalInvocationID",
+ symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_GlobalInvocationID"),
globalInvocationIDType);
const TType *localInvocationIndexType =
StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>();
- symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex",
+ symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationIndex"),
localInvocationIndexType);
break;
}
@@ -1054,10 +1099,10 @@
TFieldList *glPerVertexFieldList = new TFieldList();
TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
TField *glPositionField =
- new TField(new TType(*positionType), NewPoolTString("gl_Position"), zeroSourceLoc);
+ new TField(new TType(*positionType), ImmutableString("gl_Position"), zeroSourceLoc);
glPerVertexFieldList->push_back(glPositionField);
- const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
+ const ImmutableString glPerVertexString("gl_PerVertex");
TInterfaceBlock *glPerVertexInBlock =
new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
TLayoutQualifier::Create(), SymbolType::BuiltIn, extension);
@@ -1069,7 +1114,8 @@
new TType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType->makeArray(0u);
glInType->realize();
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_in"),
+ glInType);
TInterfaceBlock *glPerVertexOutBlock =
new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
@@ -1077,20 +1123,21 @@
TType *glPositionInBlockType = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
glPositionInBlockType->setInterfaceBlock(glPerVertexOutBlock);
glPositionInBlockType->realize();
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position",
- glPositionInBlockType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
+ ImmutableString("gl_Position"), glPositionInBlockType);
const TType *primitiveIDInType =
StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>();
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveIDIn",
- primitiveIDInType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
+ ImmutableString("gl_PrimitiveIDIn"), primitiveIDInType);
const TType *invocationIDType =
StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>();
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID",
- invocationIDType);
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
- primitiveIDType);
- symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", layerType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
+ ImmutableString("gl_InvocationID"), invocationIDType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
+ ImmutableString("gl_PrimitiveID"), primitiveIDType);
+ symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Layer"),
+ layerType);
break;
}
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index b3035c3..a2f258e 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -178,7 +178,8 @@
TIntermTyped *initializedSymbol = nullptr;
if (var.isBuiltIn())
{
- initializedSymbol = ReferenceBuiltInVariable(name, *symbolTable, shaderVersion);
+ initializedSymbol = ReferenceBuiltInVariable(ImmutableString(name.c_str()),
+ *symbolTable, shaderVersion);
if (initializedSymbol->getQualifier() == EvqFragData &&
!IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers))
{
@@ -194,7 +195,8 @@
}
else
{
- initializedSymbol = ReferenceGlobalVariable(name, *symbolTable);
+ initializedSymbol =
+ ReferenceGlobalVariable(ImmutableString(name.c_str()), *symbolTable);
}
ASSERT(initializedSymbol != nullptr);
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 965327c..c40a093 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -18,6 +18,7 @@
#include "common/mathutil.h"
#include "common/matrix_utils.h"
#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
@@ -326,7 +327,7 @@
return mVariable->uniqueId();
}
-const TString &TIntermSymbol::getName() const
+ImmutableString TIntermSymbol::getName() const
{
return mVariable->name();
}
@@ -503,7 +504,7 @@
}
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
// All other functions that take a sampler are assumed to be texture functions.
- if (mFunction->name().find("textureSize") == 0)
+ if (mFunction->name() == "textureSize")
mType.setPrecision(EbpHigh);
else
mType.setPrecision(precision);
@@ -517,7 +518,7 @@
case EOpCallInternalRawFunction:
case EOpCallBuiltInFunction:
case EOpCallFunctionInAST:
- return mFunction->name().c_str();
+ return mFunction->name().data();
default:
return GetOperatorString(mOp);
}
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 764c11e..b7456b7 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -31,6 +31,8 @@
namespace sh
{
+class ImmutableString;
+
class TDiagnostics;
class TIntermTraverser;
@@ -248,7 +250,7 @@
const TType &getType() const override;
const TSymbolUniqueId &uniqueId() const;
- const TString &getName() const;
+ ImmutableString getName() const;
const TVariable &variable() const { return *mVariable; }
void traverse(TIntermTraverser *it) override;
diff --git a/src/compiler/translator/IntermNode_util.cpp b/src/compiler/translator/IntermNode_util.cpp
index 1cbbcd4..cbe71ce 100644
--- a/src/compiler/translator/IntermNode_util.cpp
+++ b/src/compiler/translator/IntermNode_util.cpp
@@ -17,13 +17,13 @@
namespace
{
-const TFunction *LookUpBuiltInFunction(const TString &name,
+const TFunction *LookUpBuiltInFunction(const char *name,
const TIntermSequence *arguments,
const TSymbolTable &symbolTable,
int shaderVersion)
{
- const TString &mangledName = TFunctionLookup::GetMangledName(name, *arguments);
- const TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion);
+ const ImmutableString &mangledName = TFunctionLookup::GetMangledName(name, *arguments);
+ const TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion);
if (symbol)
{
ASSERT(symbol->isFunction());
@@ -150,7 +150,7 @@
ASSERT(symbolTable != nullptr);
// TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
// variable. This might need to be done in other places as well.
- return new TVariable(symbolTable, nullptr, type, SymbolType::AngleInternal);
+ return new TVariable(symbolTable, ImmutableString(""), type, SymbolType::AngleInternal);
}
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier)
@@ -234,14 +234,14 @@
return blockNode;
}
-TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable)
+TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name, const TSymbolTable &symbolTable)
{
const TVariable *var = reinterpret_cast<const TVariable *>(symbolTable.findGlobal(name));
ASSERT(var);
return new TIntermSymbol(var);
}
-TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
const TSymbolTable &symbolTable,
int shaderVersion)
{
@@ -251,7 +251,7 @@
return new TIntermSymbol(var);
}
-TIntermTyped *CreateBuiltInFunctionCallNode(const TString &name,
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
TIntermSequence *arguments,
const TSymbolTable &symbolTable,
int shaderVersion)
diff --git a/src/compiler/translator/IntermNode_util.h b/src/compiler/translator/IntermNode_util.h
index 9f3c0f2..99a6b00 100644
--- a/src/compiler/translator/IntermNode_util.h
+++ b/src/compiler/translator/IntermNode_util.h
@@ -49,14 +49,15 @@
TIntermBlock *EnsureBlock(TIntermNode *node);
// Should be called from inside Compiler::compileTreeImpl() where the global level is in scope.
-TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable);
+TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable);
// Note: this can access desktop GLSL built-ins that are hidden from the parser.
-TIntermSymbol *ReferenceBuiltInVariable(const TString &name,
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
const TSymbolTable &symbolTable,
int shaderVersion);
-TIntermTyped *CreateBuiltInFunctionCallNode(const TString &name,
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
TIntermSequence *arguments,
const TSymbolTable &symbolTable,
int shaderVersion);
diff --git a/src/compiler/translator/OutputGLSL.cpp b/src/compiler/translator/OutputGLSL.cpp
index 5e58920..9f8bbce 100644
--- a/src/compiler/translator/OutputGLSL.cpp
+++ b/src/compiler/translator/OutputGLSL.cpp
@@ -49,7 +49,7 @@
}
// Some built-ins get a special translation.
- const TString &name = node->getName();
+ const ImmutableString &name = node->getName();
if (name == "gl_FragDepthEXT")
{
out << "gl_FragDepth";
@@ -76,7 +76,7 @@
}
}
-TString TOutputGLSL::translateTextureFunction(const TString &name)
+ImmutableString TOutputGLSL::translateTextureFunction(const ImmutableString &name)
{
static const char *simpleRename[] = {"texture2DLodEXT",
"texture2DLod",
@@ -108,7 +108,7 @@
{
if (name == mapping[i])
{
- return mapping[i + 1];
+ return ImmutableString(mapping[i + 1]);
}
}
diff --git a/src/compiler/translator/OutputGLSL.h b/src/compiler/translator/OutputGLSL.h
index c80abec..b676a79 100644
--- a/src/compiler/translator/OutputGLSL.h
+++ b/src/compiler/translator/OutputGLSL.h
@@ -28,7 +28,7 @@
protected:
bool writeVariablePrecision(TPrecision) override;
void visitSymbol(TIntermSymbol *node) override;
- TString translateTextureFunction(const TString &name) override;
+ ImmutableString translateTextureFunction(const ImmutableString &name) override;
};
} // namespace sh
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index b3e8476..2e19264 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -1108,17 +1108,18 @@
}
}
-TString TOutputGLSLBase::getTypeName(const TType &type)
+ImmutableString TOutputGLSLBase::getTypeName(const TType &type)
{
return GetTypeName(type, mHashFunction, &mNameMap);
}
-TString TOutputGLSLBase::hashName(const TSymbol *symbol)
+ImmutableString TOutputGLSLBase::hashName(const TSymbol *symbol)
{
return HashName(symbol, mHashFunction, &mNameMap);
}
-TString TOutputGLSLBase::hashFieldName(const TSymbol *containingStruct, const TString &fieldName)
+ImmutableString TOutputGLSLBase::hashFieldName(const TSymbol *containingStruct,
+ const ImmutableString &fieldName)
{
if (containingStruct->symbolType() == SymbolType::UserDefined ||
containingStruct->symbolType() == SymbolType::Empty)
@@ -1131,7 +1132,7 @@
}
}
-TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
+ImmutableString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
{
if (func->isMain())
{
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index 95a7ed8..f2492e9 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -34,7 +34,7 @@
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name. Has special handling for internal names and built-ins,
// which are not hashed.
- TString hashName(const TSymbol *symbol);
+ ImmutableString hashName(const TSymbol *symbol);
protected:
TInfoSinkBase &objSink() { return mObjSink; }
@@ -47,7 +47,7 @@
void writeFunctionParameters(const TIntermSequence &args);
const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion);
void writeConstructorTriplet(Visit visit, const TType &type);
- TString getTypeName(const TType &type);
+ ImmutableString getTypeName(const TType &type);
void visitSymbol(TIntermSymbol *node) override;
void visitConstantUnion(TIntermConstantUnion *node) override;
@@ -69,11 +69,12 @@
void visitCodeBlock(TIntermBlock *node);
- TString hashFieldName(const TSymbol *containingStruct, const TString &fieldName);
+ ImmutableString hashFieldName(const TSymbol *containingStruct,
+ const ImmutableString &fieldName);
// Same as hashName(), but without hashing "main".
- TString hashFunctionNameIfNeeded(const TFunction *func);
+ ImmutableString hashFunctionNameIfNeeded(const TFunction *func);
// Used to translate function names for differences between ESSL and GLSL
- virtual TString translateTextureFunction(const TString &name) { return name; }
+ virtual ImmutableString translateTextureFunction(const ImmutableString &name) { return name; }
private:
bool structDeclared(const TStructure *structure) const;
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 55c57c9..6f59129 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -371,7 +371,8 @@
if (mappedStruct.blockDeclarator->variable().symbolType() != SymbolType::Empty)
{
- const TString &instanceName = mappedStruct.blockDeclarator->variable().name();
+ const ImmutableString &instanceName =
+ mappedStruct.blockDeclarator->variable().name();
unsigned int instanceStringArrayIndex = GL_INVALID_INDEX;
if (isInstanceArray)
instanceStringArrayIndex = instanceArrayIndex;
@@ -415,7 +416,7 @@
for (const auto &varying : mReferencedVaryings)
{
const TType &type = varying.second->getType();
- const TString &name = varying.second->name();
+ const ImmutableString &name = varying.second->name();
// Program linking depends on this exact format
varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) +
@@ -426,7 +427,7 @@
for (const auto &attribute : mReferencedAttributes)
{
const TType &type = attribute.second->getType();
- const TString &name = attribute.second->name();
+ const ImmutableString &name = attribute.second->name();
attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) +
" = " + zeroInitializer(type) + ";\n";
@@ -498,12 +499,11 @@
{
for (const auto &outputVariable : mReferencedOutputVariables)
{
- const TString &variableName = outputVariable.second->name();
+ const ImmutableString &variableName = outputVariable.second->name();
const TType &variableType = outputVariable.second->getType();
- out << "static " + TypeString(variableType) + " out_" + variableName +
- ArrayString(variableType) + " = " + zeroInitializer(variableType) +
- ";\n";
+ out << "static " << TypeString(variableType) << " out_" << variableName
+ << ArrayString(variableType) << " = " << zeroInitializer(variableType) << ";\n";
}
}
else
@@ -883,7 +883,7 @@
out << "map";
}
- const TString &name = variable.name();
+ const ImmutableString &name = variable.name();
const TSymbolUniqueId &uniqueId = variable.uniqueId();
if (name == "gl_DepthRange")
@@ -1314,11 +1314,11 @@
{
if (indexingReturnsSampler)
{
- out << "_" + field->name();
+ out << "_" << field->name();
}
else
{
- out << "." + DecorateField(field->name(), *structure);
+ out << "." << DecorateField(field->name(), *structure);
}
return false;
@@ -1661,7 +1661,7 @@
return true;
}
-TString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
+ImmutableString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
{
if (node->getAsSymbolNode())
{
@@ -1675,9 +1675,9 @@
{
int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
- TInfoSinkBase prefixSink;
+ std::stringstream prefixSink;
prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index;
- return TString(prefixSink.c_str());
+ return ImmutableString(prefixSink.str());
}
case EOpIndexDirectStruct:
{
@@ -1685,14 +1685,14 @@
int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
const TField *field = s->fields()[index];
- TInfoSinkBase prefixSink;
+ std::stringstream prefixSink;
prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_"
<< field->name();
- return TString(prefixSink.c_str());
+ return ImmutableString(prefixSink.str());
}
default:
UNREACHABLE();
- return TString("");
+ return ImmutableString("");
}
}
@@ -1951,16 +1951,16 @@
}
else if (node->getFunction()->isImageFunction())
{
- const TString &name = node->getFunction()->name();
+ const ImmutableString &name = node->getFunction()->name();
TType type = (*arguments)[0]->getAsTyped()->getType();
- TString imageFunctionName = mImageFunctionHLSL->useImageFunction(
+ TString imageFunctionName = mImageFunctionHLSL->useImageFunction(
name, type.getBasicType(), type.getLayoutQualifier().imageInternalFormat,
type.getMemoryQualifier().readonly);
out << imageFunctionName << "(";
}
else
{
- const TString &name = node->getFunction()->name();
+ const ImmutableString &name = node->getFunction()->name();
TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
int coords = 0; // textureSize(gsampler2DMS) doesn't have a second argument.
if (arguments->size() > 1)
@@ -1988,8 +1988,10 @@
{
const TType &argType = typedArg->getType();
TVector<const TVariable *> samplerSymbols;
- TString structName = samplerNamePrefixFromStruct(typedArg);
- argType.createSamplerSymbols("angle_" + structName, "", &samplerSymbols,
+ ImmutableString structName = samplerNamePrefixFromStruct(typedArg);
+ std::string namePrefix = "angle_";
+ namePrefix += structName.data();
+ argType.createSamplerSymbols(ImmutableString(namePrefix), "", &samplerSymbols,
nullptr, mSymbolTable);
for (const TVariable *sampler : samplerSymbols)
{
@@ -2002,7 +2004,7 @@
{
// In case of HLSL 4.1+, this symbol is the sampler index, and in case
// of D3D9, it's the sampler variable.
- out << ", " + sampler->name();
+ out << ", " << sampler->name();
}
}
}
@@ -2683,7 +2685,10 @@
{
ASSERT(qualifier != EvqOut && qualifier != EvqInOut);
TVector<const TVariable *> samplerSymbols;
- type.createSamplerSymbols("angle" + nameStr, "", &samplerSymbols, nullptr, mSymbolTable);
+ std::string namePrefix = "angle";
+ namePrefix += nameStr.c_str();
+ type.createSamplerSymbols(ImmutableString(namePrefix), "", &samplerSymbols, nullptr,
+ mSymbolTable);
for (const TVariable *sampler : samplerSymbols)
{
const TType &samplerType = sampler->getType();
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index 962babf..8b632a8 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -15,6 +15,7 @@
#include "compiler/translator/ASTMetadataHLSL.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/FlagStd140Structs.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermTraverse.h"
class BuiltInFunctionEmulator;
@@ -252,7 +253,7 @@
private:
TString generateStructMapping(const std::vector<MappedStruct> &std140Structs) const;
- TString samplerNamePrefixFromStruct(TIntermTyped *node);
+ ImmutableString samplerNamePrefixFromStruct(TIntermTyped *node);
bool ancestorEvaluatesToSamplerInStruct();
};
}
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index dc7ba1c..d912576 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -33,15 +33,26 @@
const int kWebGLMaxStructNesting = 4;
-const std::array<const char *, 8> kAtomicBuiltin = {{"atomicAdd", "atomicMin", "atomicMax",
- "atomicAnd", "atomicOr", "atomicXor",
- "atomicExchange", "atomicCompSwap"}};
+constexpr const ImmutableString kTexelFetchOffsetName("texelFetchOffsetName");
+constexpr const ImmutableString kTextureLodOffsetName("textureLodOffset");
+constexpr const ImmutableString kTextureProjLodOffsetName("textureProjLodOffset");
+constexpr const ImmutableString kTextureGradOffsetName("textureGradOffset");
+constexpr const ImmutableString kTextureProjGradOffsetName("textureProjGradOffset");
+constexpr const ImmutableString kTextureOffsetName("textureOffset");
+constexpr const ImmutableString kTextureProjOffsetName("textureProjOffset");
+constexpr const ImmutableString kTextureGatherName("textureGather");
+constexpr const ImmutableString kTextureGatherOffsetName("textureGatherOffset");
-bool IsAtomicBuiltin(const TString &name)
+constexpr const std::array<ImmutableString, 8> kAtomicBuiltin = {
+ {ImmutableString("atomicAdd"), ImmutableString("atomicMin"), ImmutableString("atomicMax"),
+ ImmutableString("atomicAnd"), ImmutableString("atomicOr"), ImmutableString("atomicXor"),
+ ImmutableString("atomicExchange"), ImmutableString("atomicCompSwap")}};
+
+bool IsAtomicBuiltin(const ImmutableString &name)
{
for (size_t i = 0; i < kAtomicBuiltin.size(); ++i)
{
- if (name.compare(kAtomicBuiltin[i]) == 0)
+ if (name == kAtomicBuiltin[i])
{
return true;
}
@@ -88,7 +99,7 @@
TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
if (imageSymbol)
{
- return imageSymbol->getName().c_str();
+ return imageSymbol->getName().data();
}
return "image";
}
@@ -244,15 +255,15 @@
}
bool TParseContext::parseVectorFields(const TSourceLoc &line,
- const TString &compString,
+ const ImmutableString &compString,
int vecSize,
TVector<int> *fieldOffsets)
{
ASSERT(fieldOffsets);
- size_t fieldCount = compString.size();
+ size_t fieldCount = compString.length();
if (fieldCount > 4u)
{
- error(line, "illegal vector field selection", compString.c_str());
+ error(line, "illegal vector field selection", compString);
return false;
}
fieldOffsets->resize(fieldCount);
@@ -318,7 +329,7 @@
fieldSet[i] = estpq;
break;
default:
- error(line, "illegal vector field selection", compString.c_str());
+ error(line, "illegal vector field selection", compString);
return false;
}
}
@@ -327,7 +338,7 @@
{
if ((*fieldOffsets)[i] >= vecSize)
{
- error(line, "vector field selection out of range", compString.c_str());
+ error(line, "vector field selection out of range", compString);
return false;
}
@@ -335,8 +346,7 @@
{
if (fieldSet[i] != fieldSet[i - 1])
{
- error(line, "illegal - vector component fields not from the same set",
- compString.c_str());
+ error(line, "illegal - vector component fields not from the same set", compString);
return false;
}
}
@@ -359,6 +369,11 @@
mDiagnostics->error(loc, reason, token);
}
+void TParseContext::error(const TSourceLoc &loc, const char *reason, const ImmutableString &token)
+{
+ mDiagnostics->error(loc, reason, token.data());
+}
+
void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token)
{
mDiagnostics->warning(loc, reason, token);
@@ -609,7 +624,7 @@
// Symbol inside an expression can't be nameless.
ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
- const char *symbol = symNode->getName().c_str();
+ const ImmutableString &symbol = symNode->getName();
std::stringstream reasonStream;
reasonStream << "l-value required (" << message << " \"" << symbol << "\")";
std::string reason = reasonStream.str();
@@ -661,33 +676,33 @@
// ESSL 3.00.5 sections 3.8 and 3.9.
// If it starts "gl_" or contains two consecutive underscores, it's reserved.
// Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a webgl shader.
-bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &identifier)
+bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier)
{
static const char *reservedErrMsg = "reserved built-in name";
- if (identifier.compare(0, 3, "gl_") == 0)
+ if (identifier.beginsWith("gl_"))
{
error(line, reservedErrMsg, "gl_");
return false;
}
if (sh::IsWebGLBasedSpec(mShaderSpec))
{
- if (identifier.compare(0, 6, "webgl_") == 0)
+ if (identifier.beginsWith("webgl_"))
{
error(line, reservedErrMsg, "webgl_");
return false;
}
- if (identifier.compare(0, 7, "_webgl_") == 0)
+ if (identifier.beginsWith("_webgl_"))
{
error(line, reservedErrMsg, "_webgl_");
return false;
}
}
- if (identifier.find("__") != TString::npos)
+ if (identifier.contains("__"))
{
error(line,
"identifiers containing two consecutive underscores (__) are reserved as "
"possible future keywords",
- identifier.c_str());
+ identifier);
return false;
}
return true;
@@ -852,12 +867,12 @@
// returns true in case of an error
//
bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
const TBasicType &type)
{
if (type == EbtVoid)
{
- error(line, "illegal use of type 'void'", identifier.c_str());
+ error(line, "illegal use of type 'void'", identifier);
return false;
}
@@ -1074,7 +1089,7 @@
// Enforce non-initializer type/qualifier rules.
void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
TType *type)
{
ASSERT(type != nullptr);
@@ -1090,16 +1105,16 @@
error(line,
"structures containing arrays may not be declared constant since they cannot be "
"initialized",
- identifier.c_str());
+ identifier);
}
else
{
- error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
+ error(line, "variables with qualifier 'const' must be initialized", identifier);
}
}
// This will make the type sized if it isn't sized yet.
- checkIsNotUnsizedArray(line, "implicitly sized arrays need to be initialized",
- identifier.c_str(), type);
+ checkIsNotUnsizedArray(line, "implicitly sized arrays need to be initialized", identifier,
+ type);
}
// Do some simple checks that are shared between all variable declarations,
@@ -1108,27 +1123,26 @@
// Returns true if declaring the variable succeeded.
//
bool TParseContext::declareVariable(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
const TType *type,
TVariable **variable)
{
ASSERT((*variable) == nullptr);
- (*variable) = new TVariable(&symbolTable, &identifier, type, SymbolType::UserDefined);
+ (*variable) = new TVariable(&symbolTable, identifier, type, SymbolType::UserDefined);
checkBindingIsValid(line, *type);
bool needsReservedCheck = true;
// gl_LastFragData may be redeclared with a new precision qualifier
- if (type->isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
+ if (type->isArray() && identifier.beginsWith("gl_LastFragData"))
{
const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
- symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxDrawBuffers"), mShaderVersion));
if (type->isArrayOfArrays())
{
- error(line, "redeclaration of gl_LastFragData as an array of arrays",
- identifier.c_str());
+ error(line, "redeclaration of gl_LastFragData as an array of arrays", identifier);
return false;
}
else if (static_cast<int>(type->getOutermostArraySize()) ==
@@ -1142,7 +1156,7 @@
else
{
error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
- identifier.c_str());
+ identifier);
return false;
}
}
@@ -1152,7 +1166,7 @@
if (!symbolTable.declareVariable(*variable))
{
- error(line, "redefinition", identifier.c_str());
+ error(line, "redefinition", identifier);
return false;
}
@@ -1544,13 +1558,13 @@
}
void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
- const TString &layoutQualifierName,
+ const ImmutableString &layoutQualifierName,
int versionRequired)
{
if (mShaderVersion < versionRequired)
{
- error(location, "invalid layout qualifier: not supported", layoutQualifierName.c_str());
+ error(location, "invalid layout qualifier: not supported", layoutQualifierName);
}
}
@@ -1790,18 +1804,18 @@
/////////////////////////////////////////////////////////////////////////////////
const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
- const TString *name,
+ const ImmutableString &name,
const TSymbol *symbol)
{
if (!symbol)
{
- error(location, "undeclared identifier", name->c_str());
+ error(location, "undeclared identifier", name);
return nullptr;
}
if (!symbol->isVariable())
{
- error(location, "variable expected", name->c_str());
+ error(location, "variable expected", name);
return nullptr;
}
@@ -1840,7 +1854,7 @@
"cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
" and (gl_FragColor, gl_SecondaryFragColorEXT)";
}
- error(location, errorMessage, name->c_str());
+ error(location, errorMessage, name);
}
// GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
@@ -1855,7 +1869,7 @@
}
TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
- const TString *name,
+ const ImmutableString &name,
const TSymbol *symbol)
{
const TVariable *variable = getNamedVariable(location, name, symbol);
@@ -1913,7 +1927,7 @@
//
// Returns true on success.
bool TParseContext::executeInitializer(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
TType *type,
TIntermTyped *initializer,
TIntermBinary **initNode)
@@ -2017,7 +2031,7 @@
}
TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
- const TString &identifier,
+ const ImmutableString &identifier,
TIntermTyped *initializer,
const TSourceLoc &loc)
{
@@ -2353,7 +2367,7 @@
}
void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
- const char *token,
+ const ImmutableString &token,
TType *type)
{
if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
@@ -2393,7 +2407,7 @@
TIntermDeclaration *TParseContext::parseSingleDeclaration(
TPublicType &publicType,
const TSourceLoc &identifierOrTypeLocation,
- const TString &identifier)
+ const ImmutableString &identifier)
{
TType *type = new TType(publicType);
if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
@@ -2423,7 +2437,7 @@
}
}
- checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), type);
+ checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier, type);
declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
identifierOrTypeLocation);
@@ -2440,7 +2454,7 @@
if (type->getBasicType() == EbtStruct)
{
TVariable *emptyVariable =
- new TVariable(&symbolTable, nullptr, type, SymbolType::Empty);
+ new TVariable(&symbolTable, ImmutableString(""), type, SymbolType::Empty);
symbol = new TIntermSymbol(emptyVariable);
}
else if (IsAtomicCounter(publicType.getBasicType()))
@@ -2476,7 +2490,7 @@
TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes)
{
@@ -2492,7 +2506,7 @@
TType *arrayType = new TType(elementType);
arrayType->makeArrays(arraySizes);
- checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), arrayType);
+ checkGeometryShaderInputAndSetArraySize(indexLocation, identifier, arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
@@ -2514,7 +2528,7 @@
TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &initLocation,
TIntermTyped *initializer)
{
@@ -2543,7 +2557,7 @@
TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation,
@@ -2580,14 +2594,14 @@
TIntermInvariantDeclaration *TParseContext::parseInvariantDeclaration(
const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &identifierLoc,
- const TString *identifier,
+ const ImmutableString &identifier,
const TSymbol *symbol)
{
TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
if (!typeQualifier.invariant)
{
- error(identifierLoc, "Expected invariant", identifier->c_str());
+ error(identifierLoc, "Expected invariant", identifier);
return nullptr;
}
if (!checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
@@ -2596,7 +2610,7 @@
}
if (!symbol)
{
- error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
+ error(identifierLoc, "undeclared identifier declared as invariant", identifier);
return nullptr;
}
if (!IsQualifierUnspecified(typeQualifier.qualifier))
@@ -2625,7 +2639,7 @@
typeQualifier.line);
checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
- symbolTable.addInvariantVarying(std::string(identifier->c_str()));
+ symbolTable.addInvariantVarying(std::string(identifier.data()));
TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
intermSymbol->setLine(identifierLoc);
@@ -2635,7 +2649,7 @@
void TParseContext::parseDeclarator(TPublicType &publicType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
TIntermDeclaration *declarationOut)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
@@ -2650,7 +2664,7 @@
TType *type = new TType(publicType);
- checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), type);
+ checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, type);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, type);
@@ -2667,7 +2681,7 @@
void TParseContext::parseArrayDeclarator(TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &arrayLocation,
const TVector<unsigned int> &arraySizes,
TIntermDeclaration *declarationOut)
@@ -2687,7 +2701,7 @@
TType *arrayType = new TType(elementType);
arrayType->makeArrays(arraySizes);
- checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), arrayType);
+ checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
@@ -2705,7 +2719,7 @@
void TParseContext::parseInitDeclarator(const TPublicType &publicType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &initLocation,
TIntermTyped *initializer,
TIntermDeclaration *declarationOut)
@@ -2736,7 +2750,7 @@
void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation,
@@ -2838,12 +2852,12 @@
{
if (mGlInVariableWithArraySize == nullptr)
{
- const TSymbol *glPerVertex = symbolTable.findBuiltIn("gl_PerVertex", 310);
+ const TSymbol *glPerVertex = symbolTable.findBuiltIn(ImmutableString("gl_PerVertex"), 310);
const TInterfaceBlock *glPerVertexBlock = static_cast<const TInterfaceBlock *>(glPerVertex);
TType *glInType = new TType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType->makeArray(inputArraySize);
mGlInVariableWithArraySize =
- new TVariable(&symbolTable, NewPoolTString("gl_in"), glInType, SymbolType::BuiltIn,
+ new TVariable(&symbolTable, ImmutableString("gl_in"), glInType, SymbolType::BuiltIn,
TExtension::EXT_geometry_shader);
}
else if (mGlInVariableWithArraySize->getType().getOutermostArraySize() != inputArraySize)
@@ -3019,7 +3033,7 @@
}
const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>(
- symbolTable.findBuiltIn("gl_MaxComputeWorkGroupSize", mShaderVersion));
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxComputeWorkGroupSize"), mShaderVersion));
const TConstantUnion *maxComputeWorkGroupSizeData =
maxComputeWorkGroupSize->getConstPointer();
@@ -3177,7 +3191,7 @@
{
if (!symbolTable.declareVariable(variable))
{
- error(location, "redefinition", param.name->c_str());
+ error(location, "redefinition", param.name);
}
}
// Unsized type of a named parameter should have already been checked and sanitized.
@@ -3197,7 +3211,7 @@
// The parameter had no name or declaring the symbol failed - either way, add a nameless
// symbol.
TVariable *emptyVariable =
- new TVariable(&symbolTable, nullptr, param.type, SymbolType::Empty);
+ new TVariable(&symbolTable, ImmutableString(""), param.type, SymbolType::Empty);
symbol = new TIntermSymbol(emptyVariable);
}
symbol->setLine(location);
@@ -3246,8 +3260,8 @@
// Check that non-void functions have at least one return statement.
if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
{
- error(location, "function does not return a value:",
- functionPrototype->getFunction()->name().c_str());
+ error(location,
+ "function does not return a value:", functionPrototype->getFunction()->name());
}
if (functionBody == nullptr)
@@ -3269,11 +3283,11 @@
{
ASSERT(function);
const TSymbol *builtIn =
- symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
+ symbolTable.findBuiltIn(ImmutableString(function->getMangledName()), getShaderVersion());
if (builtIn)
{
- error(location, "built-in functions cannot be redefined", function->name().c_str());
+ error(location, "built-in functions cannot be redefined", function->name());
}
else
{
@@ -3282,7 +3296,7 @@
symbolTable.setUserDefinedFunctionParameterNamesFromDefinition(function, &wasDefined);
if (wasDefined)
{
- error(location, "function already has a body", function->name().c_str());
+ error(location, "function already has a body", function->name());
}
}
@@ -3305,7 +3319,7 @@
// here.
//
const TFunction *prevDec = static_cast<const TFunction *>(
- symbolTable.find(function->getMangledName(), getShaderVersion()));
+ symbolTable.find(ImmutableString(function->getMangledName()), getShaderVersion()));
for (size_t i = 0u; i < function->getParamCount(); ++i)
{
@@ -3314,17 +3328,17 @@
{
// ESSL 3.00.6 section 12.10.
error(location, "Function parameter type cannot be a structure definition",
- function->name().c_str());
+ function->name());
}
}
if (getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltInForShaderVersion(
- function->name().c_str(), getShaderVersion()))
+ function->name().data(), getShaderVersion()))
{
// With ESSL 3.00 and above, names of built-in functions cannot be redeclared as functions.
// Therefore overloading or redefining builtin functions is an error.
error(location, "Name of a built-in function cannot be redeclared as function",
- function->name().c_str());
+ function->name());
}
else if (prevDec)
{
@@ -3352,7 +3366,7 @@
{
if (!prevSym->isFunction())
{
- error(location, "redefinition of a function", function->name().c_str());
+ error(location, "redefinition of a function", function->name());
}
insertUnmangledName = false;
}
@@ -3362,7 +3376,7 @@
symbolTable.declareUserDefinedFunction(function, insertUnmangledName);
// Raise error message if main function takes any parameters or return anything other than void
- if (function->name() == "main")
+ if (function->isMain())
{
if (function->getParamCount() > 0)
{
@@ -3384,7 +3398,7 @@
}
TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
- const TString *name,
+ const ImmutableString &name,
const TSourceLoc &location)
{
if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
@@ -3418,7 +3432,7 @@
return new TFunction(&symbolTable, name, new TType(type), SymbolType::UserDefined, false);
}
-TFunctionLookup *TParseContext::addNonConstructorFunc(const TString *name)
+TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name)
{
return TFunctionLookup::CreateFunctionCall(name);
}
@@ -3448,7 +3462,7 @@
void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
const char *errorMessage,
- const char *token,
+ const ImmutableString &token,
TType *arrayType)
{
if (arrayType->isUnsizedArray())
@@ -3459,30 +3473,29 @@
}
TParameter TParseContext::parseParameterDeclarator(TType *type,
- const TString *name,
+ const ImmutableString &name,
const TSourceLoc &nameLoc)
{
ASSERT(type);
- checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name->c_str(),
- type);
+ checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name, type);
if (type->getBasicType() == EbtVoid)
{
- error(nameLoc, "illegal use of type 'void'", name->c_str());
+ error(nameLoc, "illegal use of type 'void'", name);
}
- checkIsNotReserved(nameLoc, *name);
- TParameter param = {name, type};
+ checkIsNotReserved(nameLoc, name);
+ TParameter param = {name.data(), type};
return param;
}
TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType,
- const TString *name,
+ const ImmutableString &name,
const TSourceLoc &nameLoc)
{
TType *type = new TType(publicType);
return parseParameterDeclarator(type, name, nameLoc);
}
-TParameter TParseContext::parseParameterArrayDeclarator(const TString *name,
+TParameter TParseContext::parseParameterArrayDeclarator(const ImmutableString &name,
const TSourceLoc &nameLoc,
const TVector<unsigned int> &arraySizes,
const TSourceLoc &arrayLoc,
@@ -3584,9 +3597,9 @@
TIntermDeclaration *TParseContext::addInterfaceBlock(
const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &nameLine,
- const TString &blockName,
+ const ImmutableString &blockName,
TFieldList *fieldList,
- const TString *instanceName,
+ const ImmutableString &instanceName,
const TSourceLoc &instanceLine,
TIntermTyped *arrayIndex,
const TSourceLoc &arrayIndexLine)
@@ -3743,7 +3756,7 @@
// ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays.
checkIsNotUnsizedArray(field->line(),
"array members of interface blocks must specify a size",
- field->name().c_str(), field->type());
+ field->name(), field->type());
}
if (typeQualifier.qualifier == EvqBuffer)
@@ -3766,10 +3779,10 @@
}
TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
- &symbolTable, &blockName, fieldList, blockLayoutQualifier, SymbolType::UserDefined);
+ &symbolTable, blockName, fieldList, blockLayoutQualifier, SymbolType::UserDefined);
if (!symbolTable.declareInterfaceBlock(interfaceBlock))
{
- error(nameLine, "redefinition of an interface block name", blockName.c_str());
+ error(nameLine, "redefinition of an interface block name", blockName);
}
TType *interfaceBlockType =
@@ -3784,7 +3797,7 @@
// instance name.
TVariable *instanceVariable =
new TVariable(&symbolTable, instanceName, interfaceBlockType,
- instanceName ? SymbolType::UserDefined : SymbolType::Empty);
+ instanceName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
if (instanceVariable->symbolType() == SymbolType::Empty)
{
@@ -3800,23 +3813,22 @@
fieldType->setQualifier(typeQualifier.qualifier);
TVariable *fieldVariable =
- new TVariable(&symbolTable, &field->name(), fieldType, SymbolType::UserDefined);
+ new TVariable(&symbolTable, field->name(), fieldType, SymbolType::UserDefined);
if (!symbolTable.declareVariable(fieldVariable))
{
error(field->line(), "redefinition of an interface block member name",
- field->name().c_str());
+ field->name());
}
}
}
else
{
- checkIsNotReserved(instanceLine, *instanceName);
+ checkIsNotReserved(instanceLine, instanceName);
// add a symbol for this interface block
if (!symbolTable.declareVariable(instanceVariable))
{
- error(instanceLine, "redefinition of an interface block instance name",
- instanceName->c_str());
+ error(instanceLine, "redefinition of an interface block instance name", instanceName);
}
}
@@ -3830,7 +3842,8 @@
return declaration;
}
-void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
+void TParseContext::enterStructDeclaration(const TSourceLoc &line,
+ const ImmutableString &identifier)
{
++mStructNestingLevel;
@@ -3872,12 +3885,11 @@
}
else
{
- reasonStream << "Reference of struct type "
- << field.type()->getStruct()->name().c_str();
+ reasonStream << "Reference of struct type " << field.type()->getStruct()->name();
}
reasonStream << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
std::string reason = reasonStream.str();
- error(line, reason.c_str(), field.name().c_str());
+ error(line, reason.c_str(), field.name());
return;
}
}
@@ -3894,7 +3906,7 @@
if (baseExpression->getAsSymbolNode())
{
error(location, " left of '[' is not of type array, matrix, or vector ",
- baseExpression->getAsSymbolNode()->getName().c_str());
+ baseExpression->getAsSymbolNode()->getName());
}
else
{
@@ -4068,7 +4080,7 @@
TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
const TSourceLoc &dotLocation,
- const TString &fieldString,
+ const ImmutableString &fieldString,
const TSourceLoc &fieldLocation)
{
if (baseExpression->isArray())
@@ -4122,7 +4134,7 @@
}
else
{
- error(dotLocation, " no such field in structure", fieldString.c_str());
+ error(dotLocation, " no such field in structure", fieldString);
return baseExpression;
}
}
@@ -4159,7 +4171,7 @@
}
else
{
- error(dotLocation, " no such field in interface block", fieldString.c_str());
+ error(dotLocation, " no such field in interface block", fieldString);
return baseExpression;
}
}
@@ -4169,20 +4181,20 @@
if (mShaderVersion < 300)
{
error(dotLocation, " field selection requires structure or vector on left hand side",
- fieldString.c_str());
+ fieldString);
}
else
{
error(dotLocation,
" field selection requires structure, vector, or interface block on left hand "
"side",
- fieldString.c_str());
+ fieldString);
}
return baseExpression;
}
}
-TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
+TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
const TSourceLoc &qualifierTypeLine)
{
TLayoutQualifier qualifier = TLayoutQualifier::Create();
@@ -4223,7 +4235,7 @@
else if (qualifierType == "location")
{
error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
- qualifierType.c_str());
+ qualifierType);
}
else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER)
{
@@ -4342,13 +4354,13 @@
else
{
- error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
}
return qualifier;
}
-void TParseContext::parseLocalSize(const TString &qualifierType,
+void TParseContext::parseLocalSize(const ImmutableString &qualifierType,
const TSourceLoc &qualifierTypeLine,
int intValue,
const TSourceLoc &intValueLine,
@@ -4421,7 +4433,7 @@
}
}
-TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
+TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
const TSourceLoc &qualifierTypeLine,
int intValue,
const TSourceLoc &intValueLine)
@@ -4505,7 +4517,7 @@
else
{
- error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
}
return qualifier;
@@ -4633,30 +4645,31 @@
mDiagnostics);
}
-TDeclarator *TParseContext::parseStructDeclarator(const TString *identifier, const TSourceLoc &loc)
+TDeclarator *TParseContext::parseStructDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc)
{
- checkIsNotReserved(loc, *identifier);
+ checkIsNotReserved(loc, identifier);
return new TDeclarator(identifier, loc);
}
-TDeclarator *TParseContext::parseStructArrayDeclarator(const TString *identifier,
+TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &identifier,
const TSourceLoc &loc,
const TVector<unsigned int> *arraySizes)
{
- checkIsNotReserved(loc, *identifier);
+ checkIsNotReserved(loc, identifier);
return new TDeclarator(identifier, arraySizes, loc);
}
void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
const TFieldList::const_iterator end,
- const TString &name,
+ const ImmutableString &name,
const TSourceLoc &location)
{
for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
{
if ((*fieldIter)->name() == name)
{
- error(location, "duplicate field name in structure", name.c_str());
+ error(location, "duplicate field name in structure", name);
}
}
}
@@ -4709,7 +4722,7 @@
checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
typeSpecifier.getBasicType());
- checkIsNonVoid(typeSpecifier.getLine(), *(*declaratorList)[0]->name(),
+ checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(),
typeSpecifier.getBasicType());
checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
@@ -4736,11 +4749,11 @@
TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
const TSourceLoc &nameLine,
- const TString *structName,
+ const ImmutableString &structName,
TFieldList *fieldList)
{
SymbolType structSymbolType = SymbolType::UserDefined;
- if (structName == nullptr)
+ if (structName.empty())
{
structSymbolType = SymbolType::Empty;
}
@@ -4752,10 +4765,10 @@
if (structSymbolType != SymbolType::Empty)
{
- checkIsNotReserved(nameLine, *structName);
+ checkIsNotReserved(nameLine, structName);
if (!symbolTable.declareStructType(structure))
{
- error(nameLine, "redefinition of a struct", structName->c_str());
+ error(nameLine, "redefinition of a struct", structName);
}
}
@@ -4785,7 +4798,7 @@
}
checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size",
- field.name().c_str(), field.type());
+ field.name(), field.type());
checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line());
@@ -5474,9 +5487,9 @@
void TParseContext::checkTextureGather(TIntermAggregate *functionCall)
{
ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
- const TString &name = functionCall->getFunction()->name();
- bool isTextureGather = (name == "textureGather");
- bool isTextureGatherOffset = (name == "textureGatherOffset");
+ const ImmutableString &name = functionCall->getFunction()->name();
+ bool isTextureGather = name == kTextureGatherName;
+ bool isTextureGatherOffset = name == kTextureGatherOffsetName;
if (isTextureGather || isTextureGatherOffset)
{
TIntermNode *componentNode = nullptr;
@@ -5522,15 +5535,14 @@
if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion)
{
error(functionCall->getLine(), "Texture component must be a constant expression",
- name.c_str());
+ name);
}
else
{
int component = componentConstantUnion->getIConst(0);
if (component < 0 || component > 3)
{
- error(functionCall->getLine(), "Component must be in the range [0;3]",
- name.c_str());
+ error(functionCall->getLine(), "Component must be in the range [0;3]", name);
}
}
}
@@ -5540,23 +5552,23 @@
void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
{
ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
- const TString &name = functionCall->getFunction()->name();
+ const ImmutableString &name = functionCall->getFunction()->name();
TIntermNode *offset = nullptr;
TIntermSequence *arguments = functionCall->getSequence();
bool useTextureGatherOffsetConstraints = false;
- if (name == "texelFetchOffset" || name == "textureLodOffset" ||
- name == "textureProjLodOffset" || name == "textureGradOffset" ||
- name == "textureProjGradOffset")
+ if (name == kTexelFetchOffsetName || name == kTextureLodOffsetName ||
+ name == kTextureProjLodOffsetName || name == kTextureGradOffsetName ||
+ name == kTextureProjGradOffsetName)
{
offset = arguments->back();
}
- else if (name == "textureOffset" || name == "textureProjOffset")
+ else if (name == kTextureOffsetName || name == kTextureProjOffsetName)
{
// A bias parameter might follow the offset parameter.
ASSERT(arguments->size() >= 3);
offset = (*arguments)[2];
}
- else if (name == "textureGatherOffset")
+ else if (name == kTextureGatherOffsetName)
{
ASSERT(arguments->size() >= 3u);
const TIntermTyped *sampler = arguments->front()->getAsTyped();
@@ -5586,8 +5598,7 @@
TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
if (offset->getAsTyped()->getQualifier() != EvqConst || !offsetConstantUnion)
{
- error(functionCall->getLine(), "Texture offset must be a constant expression",
- name.c_str());
+ error(functionCall->getLine(), "Texture offset must be a constant expression", name);
}
else
{
@@ -5617,7 +5628,7 @@
void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
{
ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
- const TString &functionName = functionCall->getFunction()->name();
+ const ImmutableString &functionName = functionCall->getFunction()->name();
if (IsAtomicBuiltin(functionName))
{
TIntermSequence *arguments = functionCall->getSequence();
@@ -5640,7 +5651,7 @@
error(memNode->getLine(),
"The value passed to the mem argument of an atomic memory function does not "
"correspond to a buffer or shared variable.",
- functionName.c_str());
+ functionName);
}
}
@@ -5648,16 +5659,16 @@
void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
{
ASSERT(functionCall->getOp() == EOpCallBuiltInFunction);
- const TString &name = functionCall->getFunction()->name();
- if (name.compare(0, 5, "image") == 0)
+ if (functionCall->getFunction()->isImageFunction())
{
+ const ImmutableString &name = functionCall->getFunction()->name();
TIntermSequence *arguments = functionCall->getSequence();
TIntermTyped *imageNode = (*arguments)[0]->getAsTyped();
const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
- if (name.compare(5, 5, "Store") == 0)
+ if (strcmp(name.data() + 5u, "Store") == 0)
{
if (memoryQualifier.readonly)
{
@@ -5666,7 +5677,7 @@
GetImageArgumentToken(imageNode));
}
}
- else if (name.compare(5, 4, "Load") == 0)
+ else if (strcmp(name.data() + 5u, "Load") == 0)
{
if (memoryQualifier.writeonly)
{
@@ -5759,7 +5770,7 @@
// So accessing fnCall->name() below is safe.
if (fnCall->name() != "length")
{
- error(loc, "invalid method", fnCall->name().c_str());
+ error(loc, "invalid method", fnCall->name());
}
else if (!fnCall->arguments().empty())
{
@@ -5793,14 +5804,14 @@
const TSymbol *symbol = symbolTable.find(fnCall->name(), mShaderVersion);
if (symbol != nullptr && !symbol->isFunction())
{
- error(loc, "function name expected", fnCall->name().c_str());
+ error(loc, "function name expected", fnCall->name());
}
else
{
symbol = symbolTable.find(fnCall->getMangledName(), mShaderVersion);
if (symbol == nullptr)
{
- error(loc, "no matching overloaded function found", fnCall->name().c_str());
+ error(loc, "no matching overloaded function found", fnCall->name());
}
else
{
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 9706236..39f92e0 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -52,6 +52,7 @@
ShShaderSpec getShaderSpec() const { return mShaderSpec; }
int numErrors() const { return mDiagnostics->numErrors(); }
void error(const TSourceLoc &loc, const char *reason, const char *token);
+ void error(const TSourceLoc &loc, const char *reason, const ImmutableString &token);
void warning(const TSourceLoc &loc, const char *reason, const char *token);
// If isError is false, a warning will be reported instead.
@@ -96,15 +97,15 @@
// This method is guaranteed to succeed, even if no variable with 'name' exists.
const TVariable *getNamedVariable(const TSourceLoc &location,
- const TString *name,
+ const ImmutableString &name,
const TSymbol *symbol);
TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
- const TString *name,
+ const ImmutableString &name,
const TSymbol *symbol);
// Look at a '.' field selector string and change it into offsets for a vector.
bool parseVectorFields(const TSourceLoc &line,
- const TString &compString,
+ const ImmutableString &compString,
int vecSize,
TVector<int> *fieldOffsets);
@@ -114,7 +115,7 @@
// Check functions - the ones that return bool return false if an error was generated.
- bool checkIsNotReserved(const TSourceLoc &line, const TString &identifier);
+ bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier);
void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
void checkIsConst(TIntermTyped *node);
@@ -128,7 +129,9 @@
unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
- bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
+ bool checkIsNonVoid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TBasicType &type);
bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
bool checkIsNotOpaqueType(const TSourceLoc &line,
@@ -165,7 +168,7 @@
void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
void checkLayoutQualifierSupported(const TSourceLoc &location,
- const TString &layoutQualifierName,
+ const ImmutableString &layoutQualifierName,
int versionRequired);
bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
const TLayoutQualifier &layoutQualifier);
@@ -193,12 +196,12 @@
// Returns true on success. *initNode may still be nullptr on success in case the initialization
// is not needed in the AST.
bool executeInitializer(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
TType *type,
TIntermTyped *initializer,
TIntermBinary **initNode);
TIntermNode *addConditionInitializer(const TPublicType &pType,
- const TString &identifier,
+ const ImmutableString &identifier,
TIntermTyped *initializer,
const TSourceLoc &loc);
TIntermNode *addLoop(TLoopType type,
@@ -218,15 +221,15 @@
TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
const TSourceLoc &identifierOrTypeLocation,
- const TString &identifier);
+ const ImmutableString &identifier);
TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes);
TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &initLocation,
TIntermTyped *initializer);
@@ -234,7 +237,7 @@
// Note that this does not apply to declarations like "type[n] a = initializer"
TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation,
@@ -243,22 +246,22 @@
TIntermInvariantDeclaration *parseInvariantDeclaration(
const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &identifierLoc,
- const TString *identifier,
+ const ImmutableString &identifier,
const TSymbol *symbol);
void parseDeclarator(TPublicType &publicType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
TIntermDeclaration *declarationOut);
void parseArrayDeclarator(TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &arrayLocation,
const TVector<unsigned int> &arraySizes,
TIntermDeclaration *declarationOut);
void parseInitDeclarator(const TPublicType &publicType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &initLocation,
TIntermTyped *initializer,
TIntermDeclaration *declarationOut);
@@ -266,7 +269,7 @@
// Parse a declarator like "a[n] = initializer"
void parseArrayInitDeclarator(const TPublicType &elementType,
const TSourceLoc &identifierLocation,
- const TString &identifier,
+ const ImmutableString &identifier,
const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation,
@@ -290,15 +293,17 @@
TIntermFunctionPrototype **prototypeOut);
TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
TFunction *parseFunctionHeader(const TPublicType &type,
- const TString *name,
+ const ImmutableString &name,
const TSourceLoc &location);
- TFunctionLookup *addNonConstructorFunc(const TString *name);
+
+ TFunctionLookup *addNonConstructorFunc(const ImmutableString &name);
TFunctionLookup *addConstructorFunc(const TPublicType &publicType);
+
TParameter parseParameterDeclarator(const TPublicType &publicType,
- const TString *name,
+ const ImmutableString &name,
const TSourceLoc &nameLoc);
- TParameter parseParameterArrayDeclarator(const TString *name,
+ TParameter parseParameterArrayDeclarator(const ImmutableString &name,
const TSourceLoc &nameLoc,
const TVector<unsigned int> &arraySizes,
const TSourceLoc &arrayLoc,
@@ -309,18 +314,18 @@
TIntermTyped *indexExpression);
TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
const TSourceLoc &dotLocation,
- const TString &fieldString,
+ const ImmutableString &fieldString,
const TSourceLoc &fieldLocation);
// Parse declarator for a single field
- TDeclarator *parseStructDeclarator(const TString *identifier, const TSourceLoc &loc);
- TDeclarator *parseStructArrayDeclarator(const TString *identifier,
+ TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc);
+ TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier,
const TSourceLoc &loc,
const TVector<unsigned int> *arraySizes);
void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
const TFieldList::const_iterator end,
- const TString &name,
+ const ImmutableString &name,
const TSourceLoc &location);
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
TFieldList *combineStructFieldLists(TFieldList *processedFields,
@@ -334,19 +339,19 @@
const TDeclaratorList *declaratorList);
TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
const TSourceLoc &nameLine,
- const TString *structName,
+ const ImmutableString &structName,
TFieldList *fieldList);
TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
const TSourceLoc &nameLine,
- const TString &blockName,
+ const ImmutableString &blockName,
TFieldList *fieldList,
- const TString *instanceName,
+ const ImmutableString &instanceName,
const TSourceLoc &instanceLine,
TIntermTyped *arrayIndex,
const TSourceLoc &arrayIndexLine);
- void parseLocalSize(const TString &qualifierType,
+ void parseLocalSize(const ImmutableString &qualifierType,
const TSourceLoc &qualifierTypeLine,
int intValue,
const TSourceLoc &intValueLine,
@@ -365,9 +370,9 @@
const TSourceLoc &intValueLine,
const std::string &intValueString,
int *numMaxVertices);
- TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
+ TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
const TSourceLoc &qualifierTypeLine);
- TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
+ TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
const TSourceLoc &qualifierTypeLine,
int intValue,
const TSourceLoc &intValueLine);
@@ -383,7 +388,7 @@
const TSourceLoc &rightQualifierLocation);
// Performs an error check for embedded struct declarations.
- void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
+ void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier);
void exitStructDeclaration();
void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
@@ -467,16 +472,16 @@
const char *reason);
bool declareVariable(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
const TType *type,
TVariable **variable);
void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
- const TString &identifier,
+ const ImmutableString &identifier,
TType *type);
TParameter parseParameterDeclarator(TType *type,
- const TString *name,
+ const ImmutableString &name,
const TSourceLoc &nameLoc);
bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
@@ -526,14 +531,14 @@
// Will set the size of the outermost array according to geometry shader input layout.
void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
- const char *token,
+ const ImmutableString &token,
TType *type);
// Will size any unsized array type so unsized arrays won't need to be taken into account
// further along the line in parsing.
void checkIsNotUnsizedArray(const TSourceLoc &line,
const char *errorMessage,
- const char *token,
+ const ImmutableString &token,
TType *arrayType);
TIntermTyped *addBinaryMathInternal(TOperator op,
diff --git a/src/compiler/translator/PruneNoOps.cpp b/src/compiler/translator/PruneNoOps.cpp
index 260760f..ebba6fa 100644
--- a/src/compiler/translator/PruneNoOps.cpp
+++ b/src/compiler/translator/PruneNoOps.cpp
@@ -114,7 +114,8 @@
{
type->setQualifier(EvqTemporary);
}
- TVariable *variable = new TVariable(mSymbolTable, nullptr, type, SymbolType::Empty);
+ TVariable *variable =
+ new TVariable(mSymbolTable, ImmutableString(""), type, SymbolType::Empty);
queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
OriginalNode::IS_DROPPED);
}
diff --git a/src/compiler/translator/RegenerateStructNames.cpp b/src/compiler/translator/RegenerateStructNames.cpp
index b841057..536f521 100644
--- a/src/compiler/translator/RegenerateStructNames.cpp
+++ b/src/compiler/translator/RegenerateStructNames.cpp
@@ -4,12 +4,19 @@
// found in the LICENSE file.
//
-#include "common/debug.h"
#include "compiler/translator/RegenerateStructNames.h"
+#include "common/debug.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+
namespace sh
{
+namespace
+{
+constexpr const ImmutableString kPrefix("_webgl_struct_");
+} // anonymous namespace
+
void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
{
ASSERT(symbol);
@@ -49,15 +56,16 @@
if (mDeclaredGlobalStructs.count(uniqueId) > 0)
return;
// Map {name} to _webgl_struct_{uniqueId}_{name}.
- const char kPrefix[] = "_webgl_struct_";
- if (userType->name().find(kPrefix) == 0)
+ if (userType->name().beginsWith(kPrefix))
{
// The name has already been regenerated.
return;
}
- std::string id = Str(uniqueId);
- TString tmp = kPrefix + TString(id.c_str());
- tmp += "_" + userType->name();
+ ImmutableStringBuilder tmp(kPrefix.length() + sizeof(uniqueId) * 2u + 1u +
+ userType->name().length());
+ tmp << kPrefix;
+ tmp.appendHex(uniqueId);
+ tmp << '_' << userType->name();
// TODO(oetuaho): Add another mechanism to change symbol names so that the const_cast is not
// needed.
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index 184c711..155e3d1 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -25,6 +25,10 @@
const TType *kIndexType = StaticType::Get<EbtInt, EbpHigh, EvqIn, 1, 1>();
+constexpr const ImmutableString kBaseName("base");
+constexpr const ImmutableString kIndexName("index");
+constexpr const ImmutableString kValueName("value");
+
std::string GetIndexFunctionName(const TType &type, bool write)
{
TInfoSinkBase nameSink;
@@ -291,10 +295,6 @@
bool mRemoveIndexSideEffectsInSubtree;
PerformanceDiagnostics *mPerfDiagnostics;
-
- const TString *mBaseName;
- const TString *mIndexName;
- const TString *mValueName;
};
RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
@@ -303,10 +303,7 @@
: TLValueTrackingTraverser(true, false, false, symbolTable),
mUsedTreeInsertion(false),
mRemoveIndexSideEffectsInSubtree(false),
- mPerfDiagnostics(perfDiagnostics),
- mBaseName(NewPoolTString("base")),
- mIndexName(NewPoolTString("index")),
- mValueName(NewPoolTString("value"))
+ mPerfDiagnostics(perfDiagnostics)
{
}
@@ -404,8 +401,7 @@
#endif
const TType &type = node->getLeft()->getType();
- TString *indexingFunctionName =
- NewPoolTString(GetIndexFunctionName(type, false).c_str());
+ ImmutableString indexingFunctionName(GetIndexFunctionName(type, false));
TFunction *indexingFunction = nullptr;
if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
{
@@ -413,8 +409,8 @@
new TFunction(mSymbolTable, indexingFunctionName, GetFieldType(type),
SymbolType::AngleInternal, true);
indexingFunction->addParameter(
- TConstParameter(mBaseName, GetBaseType(type, false)));
- indexingFunction->addParameter(TConstParameter(mIndexName, kIndexType));
+ TConstParameter(kBaseName, GetBaseType(type, false)));
+ indexingFunction->addParameter(TConstParameter(kIndexName, kIndexType));
mIndexedVecAndMatrixTypes[type] = indexingFunction;
}
else
@@ -457,18 +453,18 @@
TFunction *indexedWriteFunction = nullptr;
if (mWrittenVecAndMatrixTypes.find(type) == mWrittenVecAndMatrixTypes.end())
{
- TString *functionName = NewPoolTString(
- GetIndexFunctionName(node->getLeft()->getType(), true).c_str());
+ ImmutableString functionName(
+ GetIndexFunctionName(node->getLeft()->getType(), true));
indexedWriteFunction =
new TFunction(mSymbolTable, functionName, StaticType::GetBasic<EbtVoid>(),
SymbolType::AngleInternal, false);
indexedWriteFunction->addParameter(
- TConstParameter(mBaseName, GetBaseType(type, true)));
- indexedWriteFunction->addParameter(TConstParameter(mIndexName, kIndexType));
+ TConstParameter(kBaseName, GetBaseType(type, true)));
+ indexedWriteFunction->addParameter(TConstParameter(kIndexName, kIndexType));
TType *valueType = GetFieldType(type);
valueType->setQualifier(EvqIn);
indexedWriteFunction->addParameter(
- TConstParameter(mValueName, static_cast<const TType *>(valueType)));
+ TConstParameter(kValueName, static_cast<const TType *>(valueType)));
mWrittenVecAndMatrixTypes[type] = indexedWriteFunction;
}
else
diff --git a/src/compiler/translator/RemoveUnreferencedVariables.cpp b/src/compiler/translator/RemoveUnreferencedVariables.cpp
index ad14648..6445eb8 100644
--- a/src/compiler/translator/RemoveUnreferencedVariables.cpp
+++ b/src/compiler/translator/RemoveUnreferencedVariables.cpp
@@ -203,8 +203,9 @@
// Already an empty declaration - nothing to do.
return;
}
- TVariable *emptyVariable = new TVariable(
- mSymbolTable, nullptr, new TType(declarator->getType()), SymbolType::Empty);
+ TVariable *emptyVariable =
+ new TVariable(mSymbolTable, ImmutableString(""), new TType(declarator->getType()),
+ SymbolType::Empty);
queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
OriginalNode::IS_DROPPED);
return;
diff --git a/src/compiler/translator/RunAtTheEndOfShader.cpp b/src/compiler/translator/RunAtTheEndOfShader.cpp
index d0a2b82..ca82a07 100644
--- a/src/compiler/translator/RunAtTheEndOfShader.cpp
+++ b/src/compiler/translator/RunAtTheEndOfShader.cpp
@@ -33,6 +33,8 @@
namespace
{
+constexpr const ImmutableString kMainString("main");
+
class ContainsReturnTraverser : public TIntermTraverser
{
public:
@@ -66,8 +68,8 @@
TSymbolTable *symbolTable)
{
// Replace main() with main0() with the same body.
- TFunction *oldMain =
- new TFunction(symbolTable, nullptr, new TType(EbtVoid), SymbolType::AngleInternal, false);
+ TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), new TType(EbtVoid),
+ SymbolType::AngleInternal, false);
TIntermFunctionDefinition *oldMainDefinition =
CreateInternalFunctionDefinitionNode(*oldMain, main->getBody());
@@ -75,8 +77,8 @@
ASSERT(replaced);
// void main()
- TFunction *newMain = new TFunction(symbolTable, NewPoolTString("main"), new TType(EbtVoid),
- SymbolType::UserDefined, false);
+ TFunction *newMain =
+ new TFunction(symbolTable, kMainString, new TType(EbtVoid), SymbolType::UserDefined, false);
TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
// {
diff --git a/src/compiler/translator/Symbol.cpp b/src/compiler/translator/Symbol.cpp
index 6ec6449..1332798 100644
--- a/src/compiler/translator/Symbol.cpp
+++ b/src/compiler/translator/Symbol.cpp
@@ -12,6 +12,7 @@
#include "compiler/translator/Symbol.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
@@ -20,12 +21,17 @@
namespace
{
+constexpr const ImmutableString kMainName("main");
+constexpr const ImmutableString kImageLoadName("imageLoad");
+constexpr const ImmutableString kImageStoreName("imageStore");
+constexpr const ImmutableString kImageSizeName("imageSize");
+
static const char kFunctionMangledNameSeparator = '(';
} // anonymous namespace
TSymbol::TSymbol(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
SymbolType symbolType,
TExtension extension)
: mName(name),
@@ -34,31 +40,32 @@
mExtension(extension)
{
ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
- ASSERT(mName != nullptr || mSymbolType == SymbolType::AngleInternal ||
+ ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
mSymbolType == SymbolType::Empty);
- ASSERT(mName == nullptr || *mName != "");
}
-const TString &TSymbol::name() const
+ImmutableString TSymbol::name() const
{
- if (mName != nullptr)
+ if (mName != "")
{
- return *mName;
+ return mName;
}
ASSERT(mSymbolType == SymbolType::AngleInternal);
- TInfoSinkBase symbolNameOut;
- symbolNameOut << "s" << mUniqueId.get();
- return *NewPoolTString(symbolNameOut.c_str());
+ int uniqueId = mUniqueId.get();
+ ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
+ symbolNameOut << 's';
+ symbolNameOut.appendHex(mUniqueId.get());
+ return symbolNameOut;
}
-const TString &TSymbol::getMangledName() const
+ImmutableString TSymbol::getMangledName() const
{
ASSERT(mSymbolType != SymbolType::Empty);
return name();
}
TVariable::TVariable(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TType *type,
SymbolType symbolType,
TExtension extension)
@@ -68,14 +75,14 @@
}
TStructure::TStructure(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TFieldList *fields,
SymbolType symbolType)
: TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
{
}
-void TStructure::createSamplerSymbols(const TString &namePrefix,
+void TStructure::createSamplerSymbols(const char *namePrefix,
const TString &apiNamePrefix,
TVector<const TVariable *> *outputSymbols,
TMap<const TVariable *, TString> *outputSymbolsToAPINames,
@@ -87,22 +94,24 @@
const TType *fieldType = field->type();
if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
{
- TString fieldName = namePrefix + "_" + field->name();
- TString fieldApiName = apiNamePrefix + "." + field->name();
- fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
- outputSymbolsToAPINames, symbolTable);
+ std::stringstream fieldName;
+ fieldName << namePrefix << "_" << field->name();
+ TString fieldApiName = apiNamePrefix + ".";
+ fieldApiName += field->name().data();
+ fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
+ outputSymbols, outputSymbolsToAPINames, symbolTable);
}
}
}
-void TStructure::setName(const TString &name)
+void TStructure::setName(const ImmutableString &name)
{
- TString *mutableName = const_cast<TString *>(mName);
+ ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
*mutableName = name;
}
TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TFieldList *fields,
const TLayoutQualifier &layoutQualifier,
SymbolType symbolType,
@@ -116,7 +125,7 @@
}
TFunction::TFunction(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TType *retType,
SymbolType symbolType,
bool knownToNotHaveSideEffects,
@@ -143,7 +152,7 @@
void TFunction::clearParameters()
{
parameters.clear();
- mangledName = nullptr;
+ mangledName = ImmutableString("");
}
void TFunction::swapParameters(const TFunction ¶metersSource)
@@ -155,27 +164,27 @@
}
}
-const TString *TFunction::buildMangledName() const
+ImmutableString TFunction::buildMangledName() const
{
- std::string newName = name().c_str();
+ std::string newName(name().data(), name().length());
newName += kFunctionMangledNameSeparator;
for (const auto &p : parameters)
{
newName += p.type->getMangledName();
}
- return NewPoolTString(newName.c_str());
+ return ImmutableString(newName);
}
bool TFunction::isMain() const
{
- return symbolType() == SymbolType::UserDefined && name() == "main";
+ return symbolType() == SymbolType::UserDefined && name() == kMainName;
}
bool TFunction::isImageFunction() const
{
return symbolType() == SymbolType::BuiltIn &&
- (name() == "imageSize" || name() == "imageLoad" || name() == "imageStore");
+ (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName);
}
} // namespace sh
diff --git a/src/compiler/translator/Symbol.h b/src/compiler/translator/Symbol.h
index cff5d7a..3675d4f 100644
--- a/src/compiler/translator/Symbol.h
+++ b/src/compiler/translator/Symbol.h
@@ -11,6 +11,7 @@
#include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolUniqueId.h"
@@ -33,7 +34,7 @@
public:
POOL_ALLOCATOR_NEW_DELETE();
TSymbol(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
@@ -43,8 +44,8 @@
}
// Don't call name() or getMangledName() for empty symbols (symbolType == SymbolType::Empty).
- const TString &name() const;
- virtual const TString &getMangledName() const;
+ ImmutableString name() const;
+ virtual ImmutableString getMangledName() const;
virtual bool isFunction() const { return false; }
virtual bool isVariable() const { return false; }
@@ -55,7 +56,7 @@
TExtension extension() const { return mExtension; }
protected:
- const TString *const mName;
+ const ImmutableString mName;
private:
const TSymbolUniqueId mUniqueId;
@@ -69,7 +70,7 @@
{
public:
TVariable(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TType *type,
SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED);
@@ -92,13 +93,14 @@
{
public:
TStructure(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TFieldList *fields,
SymbolType symbolType);
bool isStruct() const override { return true; }
- void createSamplerSymbols(const TString &namePrefix,
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const char *namePrefix,
const TString &apiNamePrefix,
TVector<const TVariable *> *outputSymbols,
TMap<const TVariable *, TString> *outputSymbolsToAPINames,
@@ -112,7 +114,7 @@
// setName(). At the moment keep this function private so only
// friend class RegenerateStructNames may call it.
friend class RegenerateStructNames;
- void setName(const TString &name);
+ void setName(const ImmutableString &name);
bool mAtGlobalScope;
};
@@ -123,7 +125,7 @@
{
public:
TInterfaceBlock(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TFieldList *fields,
const TLayoutQualifier &layoutQualifier,
SymbolType symbolType,
@@ -142,17 +144,17 @@
// Immutable version of TParameter.
struct TConstParameter
{
- TConstParameter() : name(nullptr), type(nullptr) {}
- explicit TConstParameter(const TString *n) : name(n), type(nullptr) {}
- explicit TConstParameter(const TType *t) : name(nullptr), type(t) {}
- TConstParameter(const TString *n, const TType *t) : name(n), type(t) {}
+ TConstParameter() : name(""), type(nullptr) {}
+ explicit TConstParameter(const ImmutableString &n) : name(n), type(nullptr) {}
+ explicit TConstParameter(const TType *t) : name(""), type(t) {}
+ TConstParameter(const ImmutableString &n, const TType *t) : name(n), type(t) {}
// Both constructor arguments must be const.
- TConstParameter(TString *n, TType *t) = delete;
- TConstParameter(const TString *n, TType *t) = delete;
- TConstParameter(TString *n, const TType *t) = delete;
+ TConstParameter(ImmutableString *n, TType *t) = delete;
+ TConstParameter(const ImmutableString *n, TType *t) = delete;
+ TConstParameter(ImmutableString *n, const TType *t) = delete;
- const TString *const name;
+ const ImmutableString name;
const TType *const type;
};
@@ -165,14 +167,14 @@
// their content cannot be modified after the call.
TConstParameter turnToConst()
{
- const TString *constName = name;
+ const ImmutableString constName(name);
const TType *constType = type;
name = nullptr;
type = nullptr;
return TConstParameter(constName, constType);
}
- const TString *name;
+ const char *name; // either pool allocated or static.
TType *type;
};
@@ -181,31 +183,32 @@
{
public:
TFunction(TSymbolTable *symbolTable,
- const TString *name,
+ const ImmutableString &name,
const TType *retType,
SymbolType symbolType,
bool knownToNotHaveSideEffects,
TOperator tOp = EOpNull,
TExtension extension = TExtension::UNDEFINED);
- ~TFunction() override;
+ virtual ~TFunction();
+
bool isFunction() const override { return true; }
void addParameter(const TConstParameter &p)
{
parameters.push_back(p);
- mangledName = nullptr;
+ mangledName = ImmutableString("");
}
void swapParameters(const TFunction ¶metersSource);
- const TString &getMangledName() const override
+ ImmutableString getMangledName() const override
{
- if (mangledName == nullptr)
+ if (mangledName == "")
{
mangledName = buildMangledName();
}
- return *mangledName;
+ return mangledName;
}
const TType &getReturnType() const { return *returnType; }
@@ -228,12 +231,12 @@
private:
void clearParameters();
- const TString *buildMangledName() const;
+ ImmutableString buildMangledName() const;
typedef TVector<TConstParameter> TParamList;
TParamList parameters;
const TType *const returnType;
- mutable const TString *mangledName;
+ mutable ImmutableString mangledName;
const TOperator op; // Only set for built-ins
bool defined;
bool mHasPrototypeDeclaration;
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 4bc29a4..f183edb 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -32,7 +32,7 @@
// Insert a function using its unmangled name as the key.
bool insertUnmangled(TFunction *function);
- TSymbol *find(const TString &name) const;
+ TSymbol *find(const ImmutableString &name) const;
void addInvariantVarying(const std::string &name) { mInvariantVaryings.insert(name); }
@@ -47,7 +47,9 @@
bool hasUnmangledBuiltIn(const char *name) const;
private:
- using tLevel = TUnorderedMap<TString, TSymbol *>;
+ using tLevel = TUnorderedMap<ImmutableString,
+ TSymbol *,
+ ImmutableString::FowlerNollVoHash<sizeof(size_t)>>;
using tLevelPair = const tLevel::value_type;
using tInsertResult = std::pair<tLevel::iterator, bool>;
@@ -74,7 +76,7 @@
return result.second;
}
-TSymbol *TSymbolTable::TSymbolTableLevel::find(const TString &name) const
+TSymbol *TSymbolTable::TSymbolTableLevel::find(const ImmutableString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
@@ -109,7 +111,7 @@
}
const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration(
- const TString &mangledName,
+ const ImmutableString &mangledName,
bool *hadPrototypeDeclarationOut)
{
TFunction *function = findUserDefinedFunction(mangledName);
@@ -139,7 +141,7 @@
return firstDeclaration;
}
-const TSymbol *TSymbolTable::find(const TString &name, int shaderVersion) const
+const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const
{
int level = currentLevel();
TSymbol *symbol = nullptr;
@@ -161,25 +163,25 @@
return symbol;
}
-TFunction *TSymbolTable::findUserDefinedFunction(const TString &name) const
+TFunction *TSymbolTable::findUserDefinedFunction(const ImmutableString &name) const
{
// User-defined functions are always declared at the global level.
ASSERT(currentLevel() >= GLOBAL_LEVEL);
return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name));
}
-const TSymbol *TSymbolTable::findGlobal(const TString &name) const
+const TSymbol *TSymbolTable::findGlobal(const ImmutableString &name) const
{
ASSERT(table.size() > GLOBAL_LEVEL);
return table[GLOBAL_LEVEL]->find(name);
}
-const TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
+const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const
{
return findBuiltIn(name, shaderVersion, false);
}
-const TSymbol *TSymbolTable::findBuiltIn(const TString &name,
+const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
int shaderVersion,
bool includeGLSLBuiltins) const
{
@@ -316,15 +318,17 @@
table[GLOBAL_LEVEL]->insert(function);
}
-TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
+TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
+ const ImmutableString &name,
+ const TType *type)
{
ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized());
- return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
+ return insertVariable(level, name, type, SymbolType::BuiltIn);
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
- const TString *name,
+ const ImmutableString &name,
const TType *type,
SymbolType symbolType)
{
@@ -339,12 +343,12 @@
TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
TExtension ext,
- const char *name,
+ const ImmutableString &name,
const TType *type)
{
ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized());
- TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
+ TVariable *var = new TVariable(this, name, type, SymbolType::BuiltIn, ext);
if (insert(level, var))
{
return var;
@@ -509,7 +513,7 @@
else
{
TFunction *function =
- new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
+ new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
function->addParameter(TConstParameter(ptype1));
@@ -576,7 +580,7 @@
{
insertUnmangledBuiltInName(name, level);
insert(level,
- new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
+ new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op));
}
void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
@@ -587,7 +591,7 @@
{
insertUnmangledBuiltInName(name, level);
insert(level,
- new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
+ new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
}
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 9a5363e..089e069 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -36,6 +36,7 @@
#include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
@@ -92,23 +93,28 @@
// The insert* entry points are used when initializing the symbol table with built-ins.
// They return the created symbol / true in case the declaration was successful, and nullptr /
// false if the declaration failed due to redefinition.
- TVariable *insertVariable(ESymbolLevel level, const char *name, const TType *type);
+ TVariable *insertVariable(ESymbolLevel level, const ImmutableString &name, const TType *type);
TVariable *insertVariableExt(ESymbolLevel level,
TExtension ext,
- const char *name,
+ const ImmutableString &name,
const TType *type);
bool insertVariable(ESymbolLevel level, TVariable *variable);
bool insertStructType(ESymbolLevel level, TStructure *str);
bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock);
template <TPrecision precision>
- bool insertConstInt(ESymbolLevel level, const char *name, int value);
+ bool insertConstInt(ESymbolLevel level, const ImmutableString &name, int value);
template <TPrecision precision>
- bool insertConstIntExt(ESymbolLevel level, TExtension ext, const char *name, int value);
+ bool insertConstIntExt(ESymbolLevel level,
+ TExtension ext,
+ const ImmutableString &name,
+ int value);
template <TPrecision precision>
- bool insertConstIvec3(ESymbolLevel level, const char *name, const std::array<int, 3> &values);
+ bool insertConstIvec3(ESymbolLevel level,
+ const ImmutableString &name,
+ const std::array<int, 3> &values);
// Note that for inserted built-in functions the const char *name needs to remain valid for the
// lifetime of the SymbolTable. SymbolTable does not allocate a copy of it.
@@ -183,18 +189,20 @@
// These return the TFunction pointer to keep using to refer to this function.
const TFunction *markUserDefinedFunctionHasPrototypeDeclaration(
- const TString &mangledName,
+ const ImmutableString &mangledName,
bool *hadPrototypeDeclarationOut);
const TFunction *setUserDefinedFunctionParameterNamesFromDefinition(const TFunction *function,
bool *wasDefinedOut);
- const TSymbol *find(const TString &name, int shaderVersion) const;
+ // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
+ // with a reference to a short-lived char * is fine to pass here.
+ const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
- const TSymbol *findGlobal(const TString &name) const;
+ const TSymbol *findGlobal(const ImmutableString &name) const;
- const TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
+ const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
- const TSymbol *findBuiltIn(const TString &name,
+ const TSymbol *findBuiltIn(const ImmutableString &name,
int shaderVersion,
bool includeGLSLBuiltins) const;
@@ -238,13 +246,13 @@
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
TVariable *insertVariable(ESymbolLevel level,
- const TString *name,
+ const ImmutableString &name,
const TType *type,
SymbolType symbolType);
bool insert(ESymbolLevel level, TSymbol *symbol);
- TFunction *findUserDefinedFunction(const TString &name) const;
+ TFunction *findUserDefinedFunction(const ImmutableString &name) const;
// Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
// above.
@@ -265,11 +273,10 @@
};
template <TPrecision precision>
-bool TSymbolTable::insertConstInt(ESymbolLevel level, const char *name, int value)
+bool TSymbolTable::insertConstInt(ESymbolLevel level, const ImmutableString &name, int value)
{
- TVariable *constant =
- new TVariable(this, NewPoolTString(name),
- StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
+ TVariable *constant = new TVariable(
+ this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
@@ -279,12 +286,11 @@
template <TPrecision precision>
bool TSymbolTable::insertConstIntExt(ESymbolLevel level,
TExtension ext,
- const char *name,
+ const ImmutableString &name,
int value)
{
- TVariable *constant = new TVariable(this, NewPoolTString(name),
- StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(),
- SymbolType::BuiltIn, ext);
+ TVariable *constant = new TVariable(
+ this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn, ext);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
@@ -293,12 +299,11 @@
template <TPrecision precision>
bool TSymbolTable::insertConstIvec3(ESymbolLevel level,
- const char *name,
+ const ImmutableString &name,
const std::array<int, 3> &values)
{
- TVariable *constantIvec3 =
- new TVariable(this, NewPoolTString(name),
- StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
+ TVariable *constantIvec3 = new TVariable(
+ this, name, StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[3];
for (size_t index = 0u; index < 3u; ++index)
diff --git a/src/compiler/translator/TextureFunctionHLSL.cpp b/src/compiler/translator/TextureFunctionHLSL.cpp
index 36898ff..96138a7 100644
--- a/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -1166,7 +1166,7 @@
std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method);
}
-TString TextureFunctionHLSL::useTextureFunction(const TString &name,
+TString TextureFunctionHLSL::useTextureFunction(const ImmutableString &name,
TBasicType samplerType,
int coords,
size_t argumentCount,
diff --git a/src/compiler/translator/TextureFunctionHLSL.h b/src/compiler/translator/TextureFunctionHLSL.h
index 68bf8c0..04d248b 100644
--- a/src/compiler/translator/TextureFunctionHLSL.h
+++ b/src/compiler/translator/TextureFunctionHLSL.h
@@ -55,7 +55,7 @@
// Returns the name of the texture function implementation to call.
// The name that's passed in is the name of the GLSL texture function that it should implement.
- TString useTextureFunction(const TString &name,
+ TString useTextureFunction(const ImmutableString &name,
TBasicType samplerType,
int coords,
size_t argumentCount,
diff --git a/src/compiler/translator/TranslatorVulkan.cpp b/src/compiler/translator/TranslatorVulkan.cpp
index 000c2f2..eec34fc 100644
--- a/src/compiler/translator/TranslatorVulkan.cpp
+++ b/src/compiler/translator/TranslatorVulkan.cpp
@@ -77,8 +77,8 @@
{
if (mInDefaultUniform)
{
- const TString &name = symbol->variable().name();
- ASSERT(name.substr(0, 3) != "gl_");
+ const ImmutableString &name = symbol->variable().name();
+ ASSERT(!name.beginsWith("gl_"));
(*mSink) << HashName(name, mHashFunction, mNameMap);
}
}
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index 47759bd..929130e 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -9,6 +9,7 @@
#endif
#include "compiler/translator/Types.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
@@ -498,13 +499,13 @@
mangledName += "struct-";
if (mStructure->symbolType() != SymbolType::Empty)
{
- mangledName += mStructure->name();
+ mangledName += mStructure->name().data();
}
mangledName += mStructure->mangledFieldList();
break;
case EbtInterfaceBlock:
mangledName += "iblock-";
- mangledName += mInterfaceBlock->name();
+ mangledName += mInterfaceBlock->name().data();
mangledName += mInterfaceBlock->mangledFieldList();
break;
default:
@@ -788,7 +789,7 @@
mMangledName = nullptr;
}
-void TType::createSamplerSymbols(const TString &namePrefix,
+void TType::createSamplerSymbols(const ImmutableString &namePrefix,
const TString &apiNamePrefix,
TVector<const TVariable *> *outputSymbols,
TMap<const TVariable *, TString> *outputSymbolsToAPINames,
@@ -802,26 +803,26 @@
elementType.toArrayElementType();
for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
{
- TStringStream elementName;
+ std::stringstream elementName;
elementName << namePrefix << "_" << arrayIndex;
TStringStream elementApiName;
elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
- elementType.createSamplerSymbols(elementName.str(), elementApiName.str(),
- outputSymbols, outputSymbolsToAPINames,
- symbolTable);
+ elementType.createSamplerSymbols(ImmutableString(elementName.str()),
+ elementApiName.str(), outputSymbols,
+ outputSymbolsToAPINames, symbolTable);
}
}
else
{
- mStructure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols,
+ mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
outputSymbolsToAPINames, symbolTable);
}
return;
}
ASSERT(IsSampler(type));
- TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()),
- new TType(*this), SymbolType::AngleInternal);
+ TVariable *variable =
+ new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
outputSymbols->push_back(variable);
if (outputSymbolsToAPINames)
{
diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
index d56b07c..47f96aa 100644
--- a/src/compiler/translator/Types.h
+++ b/src/compiler/translator/Types.h
@@ -12,6 +12,7 @@
#include "compiler/translator/BaseTypes.h"
#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/SymbolUniqueId.h"
namespace sh
@@ -30,22 +31,21 @@
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TField(TType *type, const TString *name, const TSourceLoc &line)
+ TField(TType *type, const ImmutableString &name, const TSourceLoc &line)
: mType(type), mName(name), mLine(line)
{
- ASSERT(mName);
}
// TODO(alokp): We should only return const type.
// Fix it by tweaking grammar.
TType *type() { return mType; }
const TType *type() const { return mType; }
- const TString &name() const { return *mName; }
+ const ImmutableString &name() const { return mName; }
const TSourceLoc &line() const { return mLine; }
private:
TType *mType;
- const TString *mName;
+ const ImmutableString mName;
const TSourceLoc mLine;
};
@@ -309,7 +309,8 @@
// several copies of it in the output code is undesirable for performance.
bool canReplaceWithConstantUnion() const;
- void createSamplerSymbols(const TString &namePrefix,
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const ImmutableString &namePrefix,
const TString &apiNamePrefix,
TVector<const TVariable *> *outputSymbols,
TMap<const TVariable *, TString> *outputSymbolsToAPINames,
diff --git a/src/compiler/translator/UniformHLSL.cpp b/src/compiler/translator/UniformHLSL.cpp
index 04f0ff7..33a5d88 100644
--- a/src/compiler/translator/UniformHLSL.cpp
+++ b/src/compiler/translator/UniformHLSL.cpp
@@ -10,6 +10,7 @@
#include "compiler/translator/UniformHLSL.h"
#include "common/utilities.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/blocklayoutHLSL.h"
@@ -21,6 +22,8 @@
namespace
{
+constexpr const ImmutableString kAngleDecorString("angle_");
+
static const char *UniformRegisterPrefix(const TType &type)
{
if (IsSampler(type.getBasicType()))
@@ -119,11 +122,11 @@
mUniformBlockRegister = registerCount;
}
-const Uniform *UniformHLSL::findUniformByName(const TString &name) const
+const Uniform *UniformHLSL::findUniformByName(const ImmutableString &name) const
{
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
- if (mUniforms[uniformIndex].name == name.c_str())
+ if (name == mUniforms[uniformIndex].name)
{
return &mUniforms[uniformIndex];
}
@@ -133,7 +136,7 @@
}
unsigned int UniformHLSL::assignUniformRegister(const TType &type,
- const TString &name,
+ const ImmutableString &name,
unsigned int *outRegisterCount)
{
unsigned int registerIndex;
@@ -210,7 +213,7 @@
for (const TVariable *uniform : group)
{
const TType &type = uniform->getType();
- const TString &name = uniform->name();
+ const ImmutableString &name = uniform->name();
unsigned int registerCount;
// The uniform might be just a regular sampler or one extracted from a struct.
@@ -379,7 +382,11 @@
{
TVector<const TVariable *> samplerSymbols;
TMap<const TVariable *, TString> symbolsToAPINames;
- type.createSamplerSymbols("angle_" + variable.name(), variable.name(),
+ ImmutableStringBuilder namePrefix(kAngleDecorString.length() +
+ variable.name().length());
+ namePrefix << kAngleDecorString;
+ namePrefix << variable.name();
+ type.createSamplerSymbols(namePrefix, TString(variable.name().data()),
&samplerSymbols, &symbolsToAPINames, symbolTable);
for (const TVariable *sampler : samplerSymbols)
{
@@ -471,7 +478,7 @@
}
unsigned int activeRegister = mUniformBlockRegister;
- mUniformBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
+ mUniformBlockRegisterMap[interfaceBlock.name().data()] = activeRegister;
if (instanceVariable != nullptr && instanceVariable->getType().isArray())
{
@@ -499,9 +506,8 @@
unsigned int registerIndex,
unsigned int arrayIndex)
{
- const TString &arrayIndexString =
- (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : "");
- const TString &blockName = interfaceBlock.name() + arrayIndexString;
+ const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? str(arrayIndex) : "");
+ const TString &blockName = TString(interfaceBlock.name().data()) + arrayIndexString;
TString hlsl;
hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) +
@@ -524,7 +530,7 @@
return hlsl;
}
-TString UniformHLSL::UniformBlockInstanceString(const TString &instanceName,
+TString UniformHLSL::UniformBlockInstanceString(const ImmutableString &instanceName,
unsigned int arrayIndex)
{
if (arrayIndex != GL_INVALID_INDEX)
diff --git a/src/compiler/translator/UniformHLSL.h b/src/compiler/translator/UniformHLSL.h
index 914d663..aa02fb1 100644
--- a/src/compiler/translator/UniformHLSL.h
+++ b/src/compiler/translator/UniformHLSL.h
@@ -15,6 +15,7 @@
namespace sh
{
+class ImmutableString;
class StructureHLSL;
class TSymbolTable;
@@ -40,7 +41,8 @@
TString uniformBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
// Used for direct index references
- static TString UniformBlockInstanceString(const TString &instanceName, unsigned int arrayIndex);
+ static TString UniformBlockInstanceString(const ImmutableString &instanceName,
+ unsigned int arrayIndex);
const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const
{
@@ -59,7 +61,7 @@
TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
TLayoutBlockStorage blockStorage);
TString uniformBlockStructString(const TInterfaceBlock &interfaceBlock);
- const Uniform *findUniformByName(const TString &name) const;
+ const Uniform *findUniformByName(const ImmutableString &name) const;
void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
const TType &type,
@@ -80,7 +82,7 @@
// Returns the uniform's register index
unsigned int assignUniformRegister(const TType &type,
- const TString &name,
+ const ImmutableString &name,
unsigned int *outRegisterCount);
unsigned int assignSamplerInStructUniformRegister(const TType &type,
const TString &name,
diff --git a/src/compiler/translator/UseInterfaceBlockFields.cpp b/src/compiler/translator/UseInterfaceBlockFields.cpp
index 40bd42a..df0c2f9 100644
--- a/src/compiler/translator/UseInterfaceBlockFields.cpp
+++ b/src/compiler/translator/UseInterfaceBlockFields.cpp
@@ -43,9 +43,8 @@
TIntermSequence *sequence,
const TSymbolTable &symbolTable)
{
- TString name = TString(var.name.c_str());
- ASSERT(name.find_last_of('[') == TString::npos);
- TIntermSymbol *symbol = ReferenceGlobalVariable(name, symbolTable);
+ ASSERT(var.name.find_last_of('[') == TString::npos);
+ TIntermSymbol *symbol = ReferenceGlobalVariable(ImmutableString(var.name), symbolTable);
AddNodeUseStatements(symbol, sequence);
}
@@ -74,8 +73,8 @@
}
else if (block.arraySize > 0u)
{
- TString name(block.instanceName.c_str());
- TIntermSymbol *arraySymbol = ReferenceGlobalVariable(name, symbolTable);
+ TIntermSymbol *arraySymbol =
+ ReferenceGlobalVariable(ImmutableString(block.instanceName), symbolTable);
for (unsigned int i = 0u; i < block.arraySize; ++i)
{
TIntermBinary *elementSymbol =
@@ -85,8 +84,8 @@
}
else
{
- TString name(block.instanceName.c_str());
- TIntermSymbol *blockSymbol = ReferenceGlobalVariable(name, symbolTable);
+ TIntermSymbol *blockSymbol =
+ ReferenceGlobalVariable(ImmutableString(block.instanceName), symbolTable);
InsertUseCode(block, blockSymbol, sequence);
}
}
diff --git a/src/compiler/translator/UtilsHLSL.cpp b/src/compiler/translator/UtilsHLSL.cpp
index 14ba353..f21598e 100644
--- a/src/compiler/translator/UtilsHLSL.cpp
+++ b/src/compiler/translator/UtilsHLSL.cpp
@@ -347,7 +347,7 @@
return TextureGroupSuffix(TextureGroup(type, imageInternalFormat));
}
-TString TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+const char *TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
{
switch (type)
{
@@ -593,7 +593,7 @@
return RWTextureString(RWTextureGroup(type, imageInternalFormat));
}
-TString RWTextureGroupSuffix(const HLSLRWTextureGroup type)
+const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type)
{
switch (type)
{
@@ -634,12 +634,14 @@
return "<unknown read and write resource>";
}
-TString RWTextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+const char *RWTextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
{
return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat));
}
-TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+const char *RWTextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
{
switch (type)
{
@@ -691,40 +693,40 @@
}
}
-TString DecorateField(const TString &string, const TStructure &structure)
+TString DecorateField(const ImmutableString &string, const TStructure &structure)
{
if (structure.symbolType() != SymbolType::BuiltIn)
{
return Decorate(string);
}
- return string;
+ return TString(string.data());
}
-TString DecoratePrivate(const TString &privateText)
+TString DecoratePrivate(const ImmutableString &privateText)
{
- return "dx_" + privateText;
+ return "dx_" + TString(privateText.data());
}
-TString Decorate(const TString &string)
+TString Decorate(const ImmutableString &string)
{
- if (string.compare(0, 3, "gl_") != 0)
+ if (!string.beginsWith("gl_"))
{
- return "_" + string;
+ return "_" + TString(string.data());
}
- return string;
+ return TString(string.data());
}
TString DecorateVariableIfNeeded(const TVariable &variable)
{
if (variable.symbolType() == SymbolType::AngleInternal)
{
- const TString &name = variable.name();
+ const ImmutableString &name = variable.name();
// The name should not have a prefix reserved for user-defined variables or functions.
- ASSERT(name.compare(0, 2, "f_") != 0);
- ASSERT(name.compare(0, 1, "_") != 0);
- return name;
+ ASSERT(!name.beginsWith("f_"));
+ ASSERT(!name.beginsWith("_"));
+ return TString(name.data());
}
else
{
@@ -737,15 +739,15 @@
if (func->symbolType() == SymbolType::AngleInternal)
{
// The name should not have a prefix reserved for user-defined variables or functions.
- ASSERT(func->name().compare(0, 2, "f_") != 0);
- ASSERT(func->name().compare(0, 1, "_") != 0);
- return func->name();
+ ASSERT(!func->name().beginsWith("f_"));
+ ASSERT(!func->name().beginsWith("_"));
+ return TString(func->name().data());
}
- ASSERT(func->name().compare(0, 3, "gl_") != 0);
+ ASSERT(!func->name().beginsWith("gl_"));
// Add an additional f prefix to functions so that they're always disambiguated from variables.
// This is necessary in the corner case where a variable declaration hides a function that it
// uses in its initializer.
- return "f_" + func->name();
+ return "f_" + TString(func->name().data());
}
TString TypeString(const TType &type)
@@ -860,7 +862,7 @@
return Decorate(structure.name());
}
- return "ss" + str(structure.uniqueId().get()) + "_" + structure.name();
+ return "ss" + str(structure.uniqueId().get()) + "_" + TString(structure.name().data());
}
TString QualifiedStructNameString(const TStructure &structure,
diff --git a/src/compiler/translator/UtilsHLSL.h b/src/compiler/translator/UtilsHLSL.h
index a6af60e..18e678d 100644
--- a/src/compiler/translator/UtilsHLSL.h
+++ b/src/compiler/translator/UtilsHLSL.h
@@ -93,25 +93,27 @@
const char *TextureGroupSuffix(const HLSLTextureGroup type);
const char *TextureGroupSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
-TString TextureTypeSuffix(const TBasicType type,
- TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat);
TString RWTextureString(const HLSLRWTextureGroup textureGroup);
TString RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
-TString RWTextureGroupSuffix(const HLSLRWTextureGroup type);
-TString RWTextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
-TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type);
+const char *RWTextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
TString SamplerString(const TBasicType type);
TString SamplerString(HLSLTextureGroup type);
// Adds a prefix to user-defined names to avoid naming clashes.
-TString Decorate(const TString &string);
+TString Decorate(const ImmutableString &string);
TString DecorateVariableIfNeeded(const TVariable &variable);
TString DecorateFunctionIfNeeded(const TFunction *func);
-TString DecorateField(const TString &string, const TStructure &structure);
-TString DecoratePrivate(const TString &privateText);
+TString DecorateField(const ImmutableString &string, const TStructure &structure);
+TString DecoratePrivate(const ImmutableString &privateText);
TString TypeString(const TType &type);
TString StructNameString(const TStructure &structure);
TString QualifiedStructNameString(const TStructure &structure,
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index 8b9eef3..b9fd73e 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -80,6 +80,7 @@
private:
void error(TSourceLoc loc, const char *reason, const char *token);
+ void error(TSourceLoc loc, const char *reason, const ImmutableString &token);
bool isLoopIndex(TIntermSymbol *symbol);
bool validateLoopType(TIntermLoop *node);
@@ -117,7 +118,7 @@
{
error(node->getLine(),
"Loop index cannot be statically assigned to within the body of the loop",
- node->getName().c_str());
+ node->getName());
}
}
@@ -161,6 +162,13 @@
mDiagnostics->error(loc, reason, token);
}
+void ValidateLimitationsTraverser::error(TSourceLoc loc,
+ const char *reason,
+ const ImmutableString &token)
+{
+ error(loc, reason, token.data());
+}
+
bool ValidateLimitationsTraverser::isLoopIndex(TIntermSymbol *symbol)
{
return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->uniqueId().get()) !=
@@ -246,7 +254,7 @@
if (!isConstExpr(declInit->getRight()))
{
error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression",
- symbol->getName().c_str());
+ symbol->getName());
return -1;
}
@@ -280,7 +288,7 @@
}
if (symbol->uniqueId().get() != indexSymbolId)
{
- error(symbol->getLine(), "Expected loop index", symbol->getName().c_str());
+ error(symbol->getLine(), "Expected loop index", symbol->getName());
return false;
}
// Relational operator is one of: > >= < <= == or !=.
@@ -302,7 +310,7 @@
if (!isConstExpr(binOp->getRight()))
{
error(binOp->getLine(), "Loop index cannot be compared with non-constant expression",
- symbol->getName().c_str());
+ symbol->getName());
return false;
}
@@ -351,7 +359,7 @@
}
if (symbol->uniqueId().get() != indexSymbolId)
{
- error(symbol->getLine(), "Expected loop index", symbol->getName().c_str());
+ error(symbol->getLine(), "Expected loop index", symbol->getName());
return false;
}
@@ -379,7 +387,7 @@
if (!isConstExpr(binOp->getRight()))
{
error(binOp->getLine(), "Loop index cannot be modified by non-constant expression",
- symbol->getName().c_str());
+ symbol->getName());
return false;
}
}
diff --git a/src/compiler/translator/ValidateOutputs.cpp b/src/compiler/translator/ValidateOutputs.cpp
index 107c845..d77a0da 100644
--- a/src/compiler/translator/ValidateOutputs.cpp
+++ b/src/compiler/translator/ValidateOutputs.cpp
@@ -23,7 +23,7 @@
void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
{
- diagnostics->error(symbol.getLine(), reason, symbol.getName().c_str());
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
}
class ValidateOutputsTraverser : public TIntermTraverser
diff --git a/src/compiler/translator/ValidateVaryingLocations.cpp b/src/compiler/translator/ValidateVaryingLocations.cpp
index dbe5c19..728059d 100644
--- a/src/compiler/translator/ValidateVaryingLocations.cpp
+++ b/src/compiler/translator/ValidateVaryingLocations.cpp
@@ -22,7 +22,7 @@
void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
{
- diagnostics->error(symbol.getLine(), reason, symbol.getName().c_str());
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
}
int GetLocationCount(const TIntermSymbol *varying, bool ignoreVaryingArraySize)
diff --git a/src/compiler/translator/VersionGLSL.cpp b/src/compiler/translator/VersionGLSL.cpp
index e9d654c..7e634a6 100644
--- a/src/compiler/translator/VersionGLSL.cpp
+++ b/src/compiler/translator/VersionGLSL.cpp
@@ -12,6 +12,11 @@
namespace sh
{
+namespace
+{
+constexpr const ImmutableString kGlPointCoordString("gl_PointCoord");
+} // anonymous namespace
+
int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
{
switch (output)
@@ -77,7 +82,8 @@
void TVersionGLSL::visitSymbol(TIntermSymbol *node)
{
- if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_PointCoord")
+ if (node->variable().symbolType() == SymbolType::BuiltIn &&
+ node->getName() == kGlPointCoordString)
{
ensureVersionIsAtLeast(GLSL_VERSION_120);
}
diff --git a/src/compiler/translator/glslang.l b/src/compiler/translator/glslang.l
index 6a52f4b..549787a 100644
--- a/src/compiler/translator/glslang.l
+++ b/src/compiler/translator/glslang.l
@@ -268,17 +268,17 @@
"isampler2DMSArray" |
"usampler2DMSArray" {
if (context->getShaderVersion() < 300) {
- yylval->lex.string = NewPoolTString(yytext);
- return check_type(yyscanner);
- }
- return reserved_word(yyscanner);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ return reserved_word(yyscanner);
}
/* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
"packed" {
if (context->getShaderVersion() >= 300)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -337,7 +337,7 @@
"using" { return reserved_word(yyscanner); }
{L}({L}|{D})* {
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -406,7 +406,7 @@
<FIELDS>{L}({L}|{D})* {
BEGIN(INITIAL);
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return FIELD_SELECTION;
}
<FIELDS>[ \t\v\f\r] {}
@@ -441,7 +441,8 @@
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
int token = IDENTIFIER;
- const TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
+ // Note that the ImmutableString used here isn't static or pool allocated - but it's fine since yytext is valid for the duration of its use.
+ const TSymbol* symbol = yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion());
if (symbol && symbol->isStruct())
{
token = TYPE_NAME;
@@ -488,7 +489,7 @@
if (context->getShaderVersion() < 300)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
else if (context->getShaderVersion() == 300)
@@ -507,7 +508,7 @@
// not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
if (context->getShaderVersion() < 300)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -523,7 +524,7 @@
// except when multiview extension is enabled
if (context->getShaderVersion() < 300 && !context->isExtensionEnabled(TExtension::OVR_multiview))
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -550,7 +551,7 @@
// not a reserved word in GLSL ES 1.00 and GLSL ES 3.00, so could be used as an identifier/type name
if (context->getShaderVersion() < 310)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -568,7 +569,7 @@
return token;
}
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -641,11 +642,11 @@
// a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target))
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return YUVCSCSTANDARDEXTCONSTANT;
}
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index 897e1e9..1fe17ee 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -63,7 +63,7 @@
%union {
struct {
union {
- TString *string;
+ const char *string; // pool allocated.
float f;
int i;
unsigned int u;
@@ -255,10 +255,7 @@
variable_identifier
: IDENTIFIER {
// The symbol table search was done in the lexical phase
- $$ = context->parseVariableIdentifier(@1, $1.string, $1.symbol);
-
- // don't delete $1.string, it's used by error recovery, and the pool
- // pop will reclaim the memory
+ $$ = context->parseVariableIdentifier(@1, ImmutableString($1.string), $1.symbol);
}
;
@@ -289,10 +286,10 @@
| YUVCSCSTANDARDEXTCONSTANT {
if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
{
- context->error(@1, "unsupported value", $1.string->c_str());
+ context->error(@1, "unsupported value", ImmutableString($1.string));
}
TConstantUnion *unionArray = new TConstantUnion[1];
- unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT($1.string->c_str()));
+ unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT(ImmutableString($1.string)));
$$ = context->addScalarLiteral(unionArray, @1);
}
| LEFT_PAREN expression RIGHT_PAREN {
@@ -311,7 +308,7 @@
$$ = $1;
}
| postfix_expression DOT FIELD_SELECTION {
- $$ = context->addFieldSelectionExpression($1, @2, *$3.string, @3);
+ $$ = context->addFieldSelectionExpression($1, @2, ImmutableString($3.string), @3);
}
| postfix_expression INC_OP {
$$ = context->addUnaryMathLValue(EOpPostIncrement, $1, @2);
@@ -387,10 +384,10 @@
$$ = context->addConstructorFunc($1);
}
| IDENTIFIER {
- $$ = context->addNonConstructorFunc($1.string);
+ $$ = context->addNonConstructorFunc(ImmutableString($1.string));
}
| FIELD_SELECTION {
- $$ = context->addNonConstructorFunc($1.string);
+ $$ = context->addNonConstructorFunc(ImmutableString($1.string));
}
;
@@ -592,7 +589,7 @@
enter_struct
: IDENTIFIER LEFT_BRACE {
- context->enterStructDeclaration(@1, *$1.string);
+ context->enterStructDeclaration(@1, ImmutableString($1.string));
$$ = $1;
}
;
@@ -609,16 +606,16 @@
$$ = nullptr;
}
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
- ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
- $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, NULL, @$, NULL, @$);
+ ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
+ $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString(""), @$, NULL, @$);
}
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
- ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
- $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, NULL, @$);
+ ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
+ $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, NULL, @$);
}
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON {
- ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
- $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, $7, @6);
+ ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
+ $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, $7, @6);
}
| type_qualifier SEMICOLON {
context->parseGlobalLayoutQualifier(*$1);
@@ -626,7 +623,7 @@
}
| type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant
{
- $$ = context->parseInvariantDeclaration(*$1, @2, $2.string, $2.symbol);
+ $$ = context->parseInvariantDeclaration(*$1, @2, ImmutableString($2.string), $2.symbol);
}
;
@@ -674,7 +671,7 @@
function_header
: fully_specified_type IDENTIFIER LEFT_PAREN {
- $$ = context->parseFunctionHeader($1, $2.string, @2);
+ $$ = context->parseFunctionHeader($1, ImmutableString($2.string), @2);
context->symbolTable.push();
context->enterFunctionDeclaration();
@@ -684,10 +681,10 @@
parameter_declarator
// Type + name
: type_specifier identifier {
- $$ = context->parseParameterDeclarator($1, $2.string, @2);
+ $$ = context->parseParameterDeclarator($1, ImmutableString($2.string), @2);
}
| type_specifier identifier array_specifier {
- $$ = context->parseParameterArrayDeclarator($2.string, @2, *($3), @3, &$1);
+ $$ = context->parseParameterArrayDeclarator(ImmutableString($2.string), @2, *($3), @3, &$1);
}
;
@@ -723,44 +720,44 @@
}
| init_declarator_list COMMA identifier {
$$ = $1;
- context->parseDeclarator($$.type, @3, *$3.string, $$.intermDeclaration);
+ context->parseDeclarator($$.type, @3, ImmutableString($3.string), $$.intermDeclaration);
}
| init_declarator_list COMMA identifier array_specifier {
$$ = $1;
- context->parseArrayDeclarator($$.type, @3, *$3.string, @4, *($4), $$.intermDeclaration);
+ context->parseArrayDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), $$.intermDeclaration);
}
| init_declarator_list COMMA identifier array_specifier EQUAL initializer {
ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)");
$$ = $1;
- context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, *($4), @5, $6, $$.intermDeclaration);
+ context->parseArrayInitDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), @5, $6, $$.intermDeclaration);
}
| init_declarator_list COMMA identifier EQUAL initializer {
$$ = $1;
- context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
+ context->parseInitDeclarator($$.type, @3, ImmutableString($3.string), @4, $5, $$.intermDeclaration);
}
;
single_declaration
: fully_specified_type {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, "");
+ $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, ImmutableString(""));
}
| fully_specified_type identifier {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string);
+ $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, ImmutableString($2.string));
}
| fully_specified_type identifier array_specifier {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, *($3));
+ $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3));
}
| fully_specified_type identifier array_specifier EQUAL initializer {
ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)");
$$.type = $1;
- $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, *($3), @4, $5);
+ $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3), @4, $5);
}
| fully_specified_type identifier EQUAL initializer {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
+ $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, ImmutableString($2.string), @3, $4);
}
;
@@ -914,16 +911,16 @@
layout_qualifier_id
: IDENTIFIER {
- $$ = context->parseLayoutQualifier(*$1.string, @1);
+ $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1);
}
| IDENTIFIER EQUAL INTCONSTANT {
- $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3);
+ $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
}
| IDENTIFIER EQUAL UINTCONSTANT {
- $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3);
+ $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
}
| SHARED {
- $$ = context->parseLayoutQualifier("shared", @1);
+ $$ = context->parseLayoutQualifier(ImmutableString("shared"), @1);
}
;
@@ -1200,11 +1197,11 @@
;
struct_specifier
- : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
- $$ = context->addStructure(@1, @2, $2.string, $5);
+ : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, ImmutableString($2.string)); } struct_declaration_list RIGHT_BRACE {
+ $$ = context->addStructure(@1, @2, ImmutableString($2.string), $5);
}
- | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
- $$ = context->addStructure(@1, @$, nullptr, $4);
+ | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, ImmutableString("")); } struct_declaration_list RIGHT_BRACE {
+ $$ = context->addStructure(@1, @$, ImmutableString(""), $4);
}
;
@@ -1239,10 +1236,10 @@
struct_declarator
: identifier {
- $$ = context->parseStructDeclarator($1.string, @1);
+ $$ = context->parseStructDeclarator(ImmutableString($1.string), @1);
}
| identifier array_specifier {
- $$ = context->parseStructArrayDeclarator($1.string, @1, $2);
+ $$ = context->parseStructArrayDeclarator(ImmutableString($1.string), @1, $2);
}
;
@@ -1361,7 +1358,7 @@
context->checkIsScalarBool($1->getLine(), $1);
}
| fully_specified_type identifier EQUAL initializer {
- $$ = context->addConditionInitializer($1, *$2.string, $4, @2);
+ $$ = context->addConditionInitializer($1, ImmutableString($2.string), $4, @2);
}
;
diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp
index c1221a8..2bf623f 100644
--- a/src/compiler/translator/glslang_lex.cpp
+++ b/src/compiler/translator/glslang_lex.cpp
@@ -2157,10 +2157,10 @@
YY_RULE_SETUP
{
if (context->getShaderVersion() < 300) {
- yylval->lex.string = NewPoolTString(yytext);
- return check_type(yyscanner);
- }
- return reserved_word(yyscanner);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ return reserved_word(yyscanner);
}
YY_BREAK
/* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
@@ -2169,7 +2169,7 @@
{
if (context->getShaderVersion() >= 300)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -2223,7 +2223,7 @@
case 184:
YY_RULE_SETUP
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
YY_BREAK
@@ -2459,7 +2459,7 @@
YY_RULE_SETUP
{
BEGIN(INITIAL);
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return FIELD_SELECTION;
}
YY_BREAK
@@ -3797,7 +3797,8 @@
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
int token = IDENTIFIER;
- const TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
+ // Note that the ImmutableString used here isn't static or pool allocated - but it's fine since yytext is valid for the duration of its use.
+ const TSymbol* symbol = yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion());
if (symbol && symbol->isStruct())
{
token = TYPE_NAME;
@@ -3844,7 +3845,7 @@
if (context->getShaderVersion() < 300)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
else if (context->getShaderVersion() == 300)
@@ -3863,7 +3864,7 @@
// not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
if (context->getShaderVersion() < 300)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -3879,7 +3880,7 @@
// except when multiview extension is enabled
if (context->getShaderVersion() < 300 && !context->isExtensionEnabled(TExtension::OVR_multiview))
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -3906,7 +3907,7 @@
// not a reserved word in GLSL ES 1.00 and GLSL ES 3.00, so could be used as an identifier/type name
if (context->getShaderVersion() < 310)
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -3924,7 +3925,7 @@
return token;
}
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
@@ -3997,11 +3998,11 @@
// a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target))
{
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return YUVCSCSTANDARDEXTCONSTANT;
}
- yylval->lex.string = NewPoolTString(yytext);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
return check_type(yyscanner);
}
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 89bd638..ead5cf5 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -304,7 +304,7 @@
struct {
union {
- TString *string;
+ const char *string; // pool allocated.
float f;
int i;
unsigned int u;
@@ -743,36 +743,36 @@
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 252, 252, 253, 256, 266, 269, 274, 279, 284,
- 289, 298, 304, 307, 310, 313, 316, 319, 325, 332,
- 338, 341, 349, 352, 358, 361, 367, 371, 378, 386,
- 389, 392, 398, 401, 404, 407, 414, 415, 416, 417,
- 425, 426, 429, 432, 439, 440, 443, 449, 450, 454,
- 461, 462, 465, 468, 471, 477, 478, 481, 487, 488,
- 495, 496, 503, 504, 511, 512, 518, 519, 525, 526,
- 532, 533, 539, 540, 546, 547, 548, 549, 553, 554,
- 555, 559, 563, 567, 571, 578, 581, 587, 594, 601,
- 604, 607, 611, 615, 619, 623, 627, 634, 641, 644,
- 651, 659, 676, 686, 689, 695, 699, 703, 707, 714,
- 721, 724, 728, 732, 737, 744, 748, 752, 756, 761,
- 768, 772, 778, 781, 787, 791, 798, 804, 808, 812,
- 815, 818, 827, 832, 836, 839, 842, 845, 848, 852,
- 855, 859, 862, 865, 868, 871, 874, 881, 888, 891,
- 894, 900, 907, 910, 916, 919, 922, 925, 931, 934,
- 941, 946, 953, 958, 969, 972, 975, 978, 981, 984,
- 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020, 1024,
- 1028, 1032, 1036, 1040, 1044, 1048, 1052, 1056, 1060, 1064,
- 1068, 1075, 1078, 1081, 1084, 1087, 1090, 1093, 1096, 1099,
- 1102, 1105, 1108, 1111, 1114, 1117, 1120, 1123, 1126, 1129,
- 1139, 1146, 1153, 1156, 1159, 1162, 1165, 1168, 1171, 1174,
- 1177, 1180, 1183, 1186, 1189, 1192, 1195, 1203, 1203, 1206,
- 1206, 1212, 1215, 1221, 1224, 1231, 1235, 1241, 1244, 1250,
- 1254, 1258, 1259, 1265, 1266, 1267, 1268, 1269, 1270, 1271,
- 1275, 1279, 1279, 1279, 1286, 1287, 1291, 1291, 1292, 1292,
- 1297, 1301, 1308, 1312, 1319, 1320, 1324, 1330, 1334, 1343,
- 1343, 1350, 1353, 1359, 1363, 1369, 1369, 1374, 1374, 1378,
- 1378, 1386, 1389, 1395, 1398, 1404, 1408, 1415, 1418, 1421,
- 1424, 1427, 1435, 1441, 1447, 1450, 1456, 1456
+ 0, 252, 252, 253, 256, 263, 266, 271, 276, 281,
+ 286, 295, 301, 304, 307, 310, 313, 316, 322, 329,
+ 335, 338, 346, 349, 355, 358, 364, 368, 375, 383,
+ 386, 389, 395, 398, 401, 404, 411, 412, 413, 414,
+ 422, 423, 426, 429, 436, 437, 440, 446, 447, 451,
+ 458, 459, 462, 465, 468, 474, 475, 478, 484, 485,
+ 492, 493, 500, 501, 508, 509, 515, 516, 522, 523,
+ 529, 530, 536, 537, 543, 544, 545, 546, 550, 551,
+ 552, 556, 560, 564, 568, 575, 578, 584, 591, 598,
+ 601, 604, 608, 612, 616, 620, 624, 631, 638, 641,
+ 648, 656, 673, 683, 686, 692, 696, 700, 704, 711,
+ 718, 721, 725, 729, 734, 741, 745, 749, 753, 758,
+ 765, 769, 775, 778, 784, 788, 795, 801, 805, 809,
+ 812, 815, 824, 829, 833, 836, 839, 842, 845, 849,
+ 852, 856, 859, 862, 865, 868, 871, 878, 885, 888,
+ 891, 897, 904, 907, 913, 916, 919, 922, 928, 931,
+ 938, 943, 950, 955, 966, 969, 972, 975, 978, 981,
+ 985, 989, 993, 997, 1001, 1005, 1009, 1013, 1017, 1021,
+ 1025, 1029, 1033, 1037, 1041, 1045, 1049, 1053, 1057, 1061,
+ 1065, 1072, 1075, 1078, 1081, 1084, 1087, 1090, 1093, 1096,
+ 1099, 1102, 1105, 1108, 1111, 1114, 1117, 1120, 1123, 1126,
+ 1136, 1143, 1150, 1153, 1156, 1159, 1162, 1165, 1168, 1171,
+ 1174, 1177, 1180, 1183, 1186, 1189, 1192, 1200, 1200, 1203,
+ 1203, 1209, 1212, 1218, 1221, 1228, 1232, 1238, 1241, 1247,
+ 1251, 1255, 1256, 1262, 1263, 1264, 1265, 1266, 1267, 1268,
+ 1272, 1276, 1276, 1276, 1283, 1284, 1288, 1288, 1289, 1289,
+ 1294, 1298, 1305, 1309, 1316, 1317, 1321, 1327, 1331, 1340,
+ 1340, 1347, 1350, 1356, 1360, 1366, 1366, 1371, 1371, 1375,
+ 1375, 1383, 1386, 1392, 1395, 1401, 1405, 1412, 1415, 1418,
+ 1421, 1424, 1432, 1438, 1444, 1447, 1453, 1453
};
#endif
@@ -2498,10 +2498,7 @@
{
// The symbol table search was done in the lexical phase
- (yyval.interm.intermTypedNode) = context->parseVariableIdentifier((yylsp[0]), (yyvsp[0].lex).string, (yyvsp[0].lex).symbol);
-
- // don't delete $1.string, it's used by error recovery, and the pool
- // pop will reclaim the memory
+ (yyval.interm.intermTypedNode) = context->parseVariableIdentifier((yylsp[0]), ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
}
break;
@@ -2559,10 +2556,10 @@
{
if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
{
- context->error((yylsp[0]), "unsupported value", (yyvsp[0].lex).string->c_str());
+ context->error((yylsp[0]), "unsupported value", ImmutableString((yyvsp[0].lex).string));
}
TConstantUnion *unionArray = new TConstantUnion[1];
- unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT((yyvsp[0].lex).string->c_str()));
+ unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT(ImmutableString((yyvsp[0].lex).string)));
(yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
}
@@ -2603,7 +2600,7 @@
case 15:
{
- (yyval.interm.intermTypedNode) = context->addFieldSelectionExpression((yyvsp[-2].interm.intermTypedNode), (yylsp[-1]), *(yyvsp[0].lex).string, (yylsp[0]));
+ (yyval.interm.intermTypedNode) = context->addFieldSelectionExpression((yyvsp[-2].interm.intermTypedNode), (yylsp[-1]), ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
}
break;
@@ -2728,7 +2725,7 @@
case 30:
{
- (yyval.interm.functionLookup) = context->addNonConstructorFunc((yyvsp[0].lex).string);
+ (yyval.interm.functionLookup) = context->addNonConstructorFunc(ImmutableString((yyvsp[0].lex).string));
}
break;
@@ -2736,7 +2733,7 @@
case 31:
{
- (yyval.interm.functionLookup) = context->addNonConstructorFunc((yyvsp[0].lex).string);
+ (yyval.interm.functionLookup) = context->addNonConstructorFunc(ImmutableString((yyvsp[0].lex).string));
}
break;
@@ -3164,7 +3161,7 @@
case 88:
{
- context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string);
+ context->enterStructDeclaration((yylsp[-1]), ImmutableString((yyvsp[-1].lex).string));
(yyval.lex) = (yyvsp[-1].lex);
}
@@ -3198,8 +3195,8 @@
case 92:
{
- ES3_OR_NEWER((yyvsp[-3].lex).string->c_str(), (yylsp[-4]), "interface blocks");
- (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-4].interm.typeQualifierBuilder), (yylsp[-3]), *(yyvsp[-3].lex).string, (yyvsp[-2].interm.fieldList), NULL, (yyloc), NULL, (yyloc));
+ ES3_OR_NEWER(ImmutableString((yyvsp[-3].lex).string), (yylsp[-4]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-4].interm.typeQualifierBuilder), (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string), (yyvsp[-2].interm.fieldList), ImmutableString(""), (yyloc), NULL, (yyloc));
}
break;
@@ -3207,8 +3204,8 @@
case 93:
{
- ES3_OR_NEWER((yyvsp[-4].lex).string->c_str(), (yylsp[-5]), "interface blocks");
- (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-5].interm.typeQualifierBuilder), (yylsp[-4]), *(yyvsp[-4].lex).string, (yyvsp[-3].interm.fieldList), (yyvsp[-1].lex).string, (yylsp[-1]), NULL, (yyloc));
+ ES3_OR_NEWER(ImmutableString((yyvsp[-4].lex).string), (yylsp[-5]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-5].interm.typeQualifierBuilder), (yylsp[-4]), ImmutableString((yyvsp[-4].lex).string), (yyvsp[-3].interm.fieldList), ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), NULL, (yyloc));
}
break;
@@ -3216,8 +3213,8 @@
case 94:
{
- ES3_OR_NEWER((yyvsp[-7].lex).string->c_str(), (yylsp[-8]), "interface blocks");
- (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-8].interm.typeQualifierBuilder), (yylsp[-7]), *(yyvsp[-7].lex).string, (yyvsp[-6].interm.fieldList), (yyvsp[-4].lex).string, (yylsp[-4]), (yyvsp[-2].interm.intermTypedNode), (yylsp[-3]));
+ ES3_OR_NEWER(ImmutableString((yyvsp[-7].lex).string), (yylsp[-8]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-8].interm.typeQualifierBuilder), (yylsp[-7]), ImmutableString((yyvsp[-7].lex).string), (yyvsp[-6].interm.fieldList), ImmutableString((yyvsp[-4].lex).string), (yylsp[-4]), (yyvsp[-2].interm.intermTypedNode), (yylsp[-3]));
}
break;
@@ -3234,7 +3231,7 @@
case 96:
{
- (yyval.interm.intermNode) = context->parseInvariantDeclaration(*(yyvsp[-2].interm.typeQualifierBuilder), (yylsp[-1]), (yyvsp[-1].lex).string, (yyvsp[-1].lex).symbol);
+ (yyval.interm.intermNode) = context->parseInvariantDeclaration(*(yyvsp[-2].interm.typeQualifierBuilder), (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string), (yyvsp[-1].lex).symbol);
}
break;
@@ -3299,7 +3296,7 @@
case 102:
{
- (yyval.interm.function) = context->parseFunctionHeader((yyvsp[-2].interm.type), (yyvsp[-1].lex).string, (yylsp[-1]));
+ (yyval.interm.function) = context->parseFunctionHeader((yyvsp[-2].interm.type), ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]));
context->symbolTable.push();
context->enterFunctionDeclaration();
@@ -3310,7 +3307,7 @@
case 103:
{
- (yyval.interm.param) = context->parseParameterDeclarator((yyvsp[-1].interm.type), (yyvsp[0].lex).string, (yylsp[0]));
+ (yyval.interm.param) = context->parseParameterDeclarator((yyvsp[-1].interm.type), ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
}
break;
@@ -3318,7 +3315,7 @@
case 104:
{
- (yyval.interm.param) = context->parseParameterArrayDeclarator((yyvsp[-1].lex).string, (yylsp[-1]), *((yyvsp[0].interm.arraySizes)), (yylsp[0]), &(yyvsp[-2].interm.type));
+ (yyval.interm.param) = context->parseParameterArrayDeclarator(ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), *((yyvsp[0].interm.arraySizes)), (yylsp[0]), &(yyvsp[-2].interm.type));
}
break;
@@ -3380,7 +3377,7 @@
{
(yyval.interm) = (yyvsp[-2].interm);
- context->parseDeclarator((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string, (yyval.interm).intermDeclaration);
+ context->parseDeclarator((yyval.interm).type, (yylsp[0]), ImmutableString((yyvsp[0].lex).string), (yyval.interm).intermDeclaration);
}
break;
@@ -3389,7 +3386,7 @@
{
(yyval.interm) = (yyvsp[-3].interm);
- context->parseArrayDeclarator((yyval.interm).type, (yylsp[-1]), *(yyvsp[-1].lex).string, (yylsp[0]), *((yyvsp[0].interm.arraySizes)), (yyval.interm).intermDeclaration);
+ context->parseArrayDeclarator((yyval.interm).type, (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string), (yylsp[0]), *((yyvsp[0].interm.arraySizes)), (yyval.interm).intermDeclaration);
}
break;
@@ -3399,7 +3396,7 @@
{
ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
(yyval.interm) = (yyvsp[-5].interm);
- context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string), (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
}
break;
@@ -3408,7 +3405,7 @@
{
(yyval.interm) = (yyvsp[-4].interm);
- context->parseInitDeclarator((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ context->parseInitDeclarator((yyval.interm).type, (yylsp[-2]), ImmutableString((yyvsp[-2].lex).string), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
}
break;
@@ -3417,7 +3414,7 @@
{
(yyval.interm).type = (yyvsp[0].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), ImmutableString(""));
}
break;
@@ -3426,7 +3423,7 @@
{
(yyval.interm).type = (yyvsp[-1].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), ImmutableString((yyvsp[0].lex).string));
}
break;
@@ -3435,7 +3432,7 @@
{
(yyval.interm).type = (yyvsp[-2].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-1]), *(yyvsp[-1].lex).string, (yylsp[0]), *((yyvsp[0].interm.arraySizes)));
+ (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string), (yylsp[0]), *((yyvsp[0].interm.arraySizes)));
}
break;
@@ -3445,7 +3442,7 @@
{
ES3_OR_NEWER("[]", (yylsp[-2]), "first-class arrays (array initializer)");
(yyval.interm).type = (yyvsp[-4].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string), (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3454,7 +3451,7 @@
{
(yyval.interm).type = (yyvsp[-3].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), ImmutableString((yyvsp[-2].lex).string), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3748,7 +3745,7 @@
case 154:
{
- (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0]));
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
}
break;
@@ -3756,7 +3753,7 @@
case 155:
{
- (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
}
break;
@@ -3764,7 +3761,7 @@
case 156:
{
- (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
}
break;
@@ -3772,7 +3769,7 @@
case 157:
{
- (yyval.interm.layoutQualifier) = context->parseLayoutQualifier("shared", (yylsp[0]));
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(ImmutableString("shared"), (yylsp[0]));
}
break;
@@ -4387,28 +4384,28 @@
case 227:
- { context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); }
+ { context->enterStructDeclaration((yylsp[-1]), ImmutableString((yyvsp[-1].lex).string)); }
break;
case 228:
{
- (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList));
+ (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-5]), (yylsp[-4]), ImmutableString((yyvsp[-4].lex).string), (yyvsp[-1].interm.fieldList));
}
break;
case 229:
- { context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string); }
+ { context->enterStructDeclaration((yylsp[0]), ImmutableString("")); }
break;
case 230:
{
- (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), nullptr, (yyvsp[-1].interm.fieldList));
+ (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), ImmutableString(""), (yyvsp[-1].interm.fieldList));
}
break;
@@ -4466,7 +4463,7 @@
case 237:
{
- (yyval.interm.declarator) = context->parseStructDeclarator((yyvsp[0].lex).string, (yylsp[0]));
+ (yyval.interm.declarator) = context->parseStructDeclarator(ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
}
break;
@@ -4474,7 +4471,7 @@
case 238:
{
- (yyval.interm.declarator) = context->parseStructArrayDeclarator((yyvsp[-1].lex).string, (yylsp[-1]), (yyvsp[0].interm.arraySizes));
+ (yyval.interm.declarator) = context->parseStructArrayDeclarator(ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), (yyvsp[0].interm.arraySizes));
}
break;
@@ -4728,7 +4725,7 @@
case 274:
{
- (yyval.interm.intermNode) = context->addConditionInitializer((yyvsp[-3].interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode), (yylsp[-2]));
+ (yyval.interm.intermNode) = context->addConditionInitializer((yyvsp[-3].interm.type), ImmutableString((yyvsp[-2].lex).string), (yyvsp[0].interm.intermTypedNode), (yylsp[-2]));
}
break;
diff --git a/src/compiler/translator/glslang_tab.h b/src/compiler/translator/glslang_tab.h
index 1f1d9b7..9aacce4 100644
--- a/src/compiler/translator/glslang_tab.h
+++ b/src/compiler/translator/glslang_tab.h
@@ -215,7 +215,7 @@
struct {
union {
- TString *string;
+ const char *string; // pool allocated.
float f;
int i;
unsigned int u;
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
index bd39cd1..9b70217 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -473,12 +473,12 @@
return arrayString.str();
}
-TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
+ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
{
if (type.getBasicType() == EbtStruct)
return HashName(type.getStruct(), hashFunction, nameMap);
else
- return type.getBuiltInTypeNameString();
+ return ImmutableString(type.getBuiltInTypeNameString());
}
bool IsVaryingOut(TQualifier qualifier)
diff --git a/src/compiler/translator/util.h b/src/compiler/translator/util.h
index 6d6dc95..4b2d662 100644
--- a/src/compiler/translator/util.h
+++ b/src/compiler/translator/util.h
@@ -13,6 +13,7 @@
#include <GLSLANG/ShaderLang.h>
#include "compiler/translator/HashNames.h"
+#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/Operator.h"
#include "compiler/translator/Types.h"
@@ -46,7 +47,7 @@
// 3.10 section 4.1.9.
TString ArrayString(const TType &type);
-TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap);
+ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap);
TType GetShaderVariableBasicType(const sh::ShaderVariable &var);