Commit 9d4d7f06 by Olli Etuaho Committed by Commit Bot

Classify TSymbols using an enum

Symbols can be either built-ins, user-defined, nameless, or for ANGLE's internal use. In addition we currently use TFunction symbols that are not yet resolved - they might later resolve to either a built-in or a user-defined function. Record this information in each TSymbol so that TSymbol contains sufficient information for deciding how to format symbol names in output. The goal is to eventually replace current uses of TName with pointers to different TSymbol objects. So far only built-ins and user-defined symbols have associated TSymbol objects, but that will be expanded to cover ANGLE's internal symbols as well. BUG=angleproject:2267 TEST=angle_unittests Change-Id: I927ce023fe257cc236da82c127700f3bd72bfe96 Reviewed-on: https://chromium-review.googlesource.com/816952 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 9af765dd
......@@ -503,7 +503,7 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
if (compileOptions & SH_REGENERATE_STRUCT_NAMES)
{
RegenerateStructNames gen(&symbolTable, shaderVersion);
RegenerateStructNames gen(&symbolTable);
root->traverse(&gen);
}
......
......@@ -754,8 +754,8 @@ void InsertBuiltInFunctions(sh::GLenum type,
fields->push_back(near);
fields->push_back(far);
fields->push_back(diff);
TStructure *depthRangeStruct =
new TStructure(&symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields);
TStructure *depthRangeStruct = new TStructure(
&symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct);
TType depthRangeType(depthRangeStruct);
depthRangeType.setQualifier(EvqUniform);
......@@ -1024,7 +1024,7 @@ void IdentifyBuiltIns(sh::GLenum type,
const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
TInterfaceBlock *glPerVertexInBlock =
new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
TLayoutQualifier::Create(), extension);
TLayoutQualifier::Create(), SymbolType::BuiltIn, extension);
symbolTable.insertInterfaceBlock(ESSL3_1_BUILTINS, glPerVertexInBlock);
// The array size of gl_in is undefined until we get a valid input primitive
......@@ -1033,8 +1033,9 @@ void IdentifyBuiltIns(sh::GLenum type,
glInType.makeArray(0u);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
TInterfaceBlock *glPerVertexOutBlock = new TInterfaceBlock(
&symbolTable, glPerVertexString, glPerVertexFieldList, TLayoutQualifier::Create());
TInterfaceBlock *glPerVertexOutBlock =
new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
TLayoutQualifier::Create(), SymbolType::BuiltIn);
TType glPositionType(EbtFloat, EbpHigh, EvqPosition, 4);
glPositionType.setInterfaceBlock(glPerVertexOutBlock);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position",
......
......@@ -188,7 +188,7 @@ bool IntermNodePatternMatcher::match(TIntermDeclaration *node)
{
TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
if (declarator->getBasicType() == EbtStruct &&
declarator->getType().getStruct()->name() == "")
declarator->getType().getStruct()->symbolType() == SymbolType::Empty)
{
return true;
}
......
......@@ -310,7 +310,7 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
declareStruct(structure);
if (!structure->name().empty())
if (structure->symbolType() != SymbolType::Empty)
{
mDeclaredStructs.insert(structure->uniqueId().get());
}
......@@ -583,7 +583,8 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
const TField *field = structure->fields()[index->getIConst(0)];
TString fieldName = field->name();
if (!mSymbolTable->findBuiltIn(structure->name(), mShaderVersion))
if (structure->symbolType() == SymbolType::UserDefined ||
structure->symbolType() == SymbolType::Empty)
fieldName = hashName(TName(fieldName));
out << fieldName;
......@@ -600,7 +601,8 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
const TField *field = interfaceBlock->fields()[index->getIConst(0)];
TString fieldName = field->name();
if (!mSymbolTable->findBuiltIn(interfaceBlock->name(), mShaderVersion))
ASSERT(interfaceBlock->symbolType() != SymbolType::Empty);
if (interfaceBlock->symbolType() == SymbolType::UserDefined)
{
fieldName = hashName(TName(fieldName));
}
......@@ -1156,7 +1158,7 @@ TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunctionSymbolInfo &inf
bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
{
ASSERT(structure);
if (structure->name().empty())
if (structure->symbolType() == SymbolType::Empty)
{
return false;
}
......
......@@ -3452,13 +3452,19 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
}
// Add the function as a prototype after parsing it (we do not support recursion)
return new TFunction(&symbolTable, name, new TType(type));
return new TFunction(&symbolTable, name, new TType(type), SymbolType::UserDefined);
}
TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSourceLoc &loc)
{
const TType *returnType = StaticType::GetQualified<EbtVoid, EvqTemporary>();
return new TFunction(&symbolTable, name, returnType);
// TODO(oetuaho): Some more appropriate data structure than TFunction could be used here. We're
// really only interested in the mangled name of the function to look up the actual function
// from the symbol table. If we just had the name string and the types of the parameters that
// would be enough, but TFunction carries a lot of extra information in addition to that.
// Besides function calls we do have to store constructor calls in the same data structure, for
// them we need to store a TType.
return new TFunction(&symbolTable, name, returnType, SymbolType::NotResolved);
}
TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
......@@ -3482,7 +3488,7 @@ TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
type->setBasicType(EbtFloat);
}
return new TFunction(&symbolTable, nullptr, type, EOpConstruct);
return new TFunction(&symbolTable, nullptr, type, SymbolType::BuiltIn, EOpConstruct);
}
void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
......@@ -3808,8 +3814,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
}
}
TInterfaceBlock *interfaceBlock =
new TInterfaceBlock(&symbolTable, &blockName, fieldList, blockLayoutQualifier);
TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
&symbolTable, &blockName, fieldList, blockLayoutQualifier, SymbolType::UserDefined);
if (!symbolTable.declareInterfaceBlock(interfaceBlock))
{
error(nameLine, "redefinition of an interface block name", blockName.c_str());
......@@ -4781,13 +4787,19 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
const TString *structName,
TFieldList *fieldList)
{
TStructure *structure = new TStructure(&symbolTable, structName, fieldList);
SymbolType structSymbolType = SymbolType::UserDefined;
if (structName == nullptr)
{
structName = NewPoolTString("");
structSymbolType = SymbolType::Empty;
}
TStructure *structure = new TStructure(&symbolTable, structName, fieldList, structSymbolType);
// Store a bool in the struct if we're at global scope, to allow us to
// skip the local struct scoping workaround in HLSL.
structure->setAtGlobalScope(symbolTable.atGlobalLevel());
if (!structName->empty())
if (structSymbolType != SymbolType::Empty)
{
checkIsNotReserved(nameLine, *structName);
if (!symbolTable.declareStructType(structure))
......
......@@ -19,7 +19,7 @@ void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
if (!userType)
return;
if (mSymbolTable->findBuiltIn(userType->name(), mShaderVersion))
if (userType->symbolType() == SymbolType::BuiltIn)
{
// Built-in struct, do not touch it.
return;
......
......@@ -18,10 +18,8 @@ namespace sh
class RegenerateStructNames : public TIntermTraverser
{
public:
RegenerateStructNames(TSymbolTable *symbolTable, int shaderVersion)
: TIntermTraverser(true, false, false, symbolTable),
mShaderVersion(shaderVersion),
mScopeDepth(0)
RegenerateStructNames(TSymbolTable *symbolTable)
: TIntermTraverser(true, false, false, symbolTable), mScopeDepth(0)
{
}
......@@ -30,8 +28,6 @@ class RegenerateStructNames : public TIntermTraverser
bool visitBlock(Visit, TIntermBlock *block) override;
private:
int mShaderVersion;
// Indicating the depth of the current scope.
// The global scope is 1.
int mScopeDepth;
......
......@@ -26,7 +26,7 @@ TString Define(const TStructure &structure,
Std140PaddingHelper *padHelper)
{
const TFieldList &fields = structure.fields();
const bool isNameless = (structure.name() == "");
const bool isNameless = (structure.symbolType() == SymbolType::Empty);
const TString &structName =
QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing);
const TString declareString = (isNameless ? "struct" : "struct " + structName);
......
......@@ -29,21 +29,32 @@ static const char kFunctionMangledNameSeparator = '(';
} // anonymous namespace
TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *name, TExtension extension)
: mName(name), mUniqueId(symbolTable->nextUniqueId()), mExtension(extension)
TSymbol::TSymbol(TSymbolTable *symbolTable,
const TString *name,
SymbolType symbolType,
TExtension extension)
: mName(name),
mUniqueId(symbolTable->nextUniqueId()),
mSymbolType(symbolType),
mExtension(extension)
{
ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
}
TVariable::TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
SymbolType symbolType,
TExtension extension)
: TSymbol(symbolTable, name, extension), type(t), unionArray(nullptr)
: TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
{
}
TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, const TFieldList *fields)
: TSymbol(symbolTable, name), TFieldListCollection(fields)
TStructure::TStructure(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
SymbolType symbolType)
: TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
{
}
......@@ -77,8 +88,9 @@ TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
const TLayoutQualifier &layoutQualifier,
SymbolType symbolType,
TExtension extension)
: TSymbol(symbolTable, name, extension),
: TSymbol(symbolTable, name, symbolType, extension),
TFieldListCollection(fields),
mBlockStorage(layoutQualifier.blockStorage),
mBinding(layoutQualifier.binding)
......@@ -322,7 +334,7 @@ constexpr const TType *VectorType(const TType *type, int size)
TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
{
return insertVariable(currentLevel(), name, type);
return insertVariable(currentLevel(), name, type, SymbolType::UserDefined);
}
bool TSymbolTable::declareStructType(TStructure *str)
......@@ -337,12 +349,16 @@ bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
{
return insertVariable(level, NewPoolTString(name), type);
ASSERT(level <= LAST_BUILTIN_LEVEL);
return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
const TString *name,
const TType &type,
SymbolType symbolType)
{
TVariable *var = new TVariable(this, name, type);
TVariable *var = new TVariable(this, name, type, symbolType);
if (insert(level, var))
{
// Do lazy initialization for struct types, so we allocate to the current scope.
......@@ -360,7 +376,7 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
const char *name,
const TType &type)
{
TVariable *var = new TVariable(this, NewPoolTString(name), type, ext);
TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
if (insert(level, var))
{
if (var->getType().getBasicType() == EbtStruct)
......@@ -515,7 +531,8 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
}
else
{
TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
TFunction *function =
new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op, ext);
function->addParameter(TConstParameter(ptype1));
......@@ -581,7 +598,7 @@ void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
const char *name)
{
insertUnmangledBuiltInName(name, level);
insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
insert(level, new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op));
}
void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
......@@ -591,7 +608,7 @@ void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
const char *name)
{
insertUnmangledBuiltInName(name, level);
insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
insert(level, new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op, ext));
}
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
......
......@@ -43,6 +43,14 @@
namespace sh
{
enum class SymbolType
{
BuiltIn,
UserDefined,
Empty, // Meaning symbol without a name.
NotResolved
};
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
......@@ -50,6 +58,7 @@ class TSymbol : angle::NonCopyable
POOL_ALLOCATOR_NEW_DELETE();
TSymbol(TSymbolTable *symbolTable,
const TString *name,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
virtual ~TSymbol()
......@@ -63,6 +72,7 @@ class TSymbol : angle::NonCopyable
virtual bool isVariable() const { return false; }
virtual bool isStruct() const { return false; }
const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
SymbolType symbolType() const { return mSymbolType; }
TExtension extension() const { return mExtension; }
protected:
......@@ -70,6 +80,7 @@ class TSymbol : angle::NonCopyable
private:
const TSymbolUniqueId mUniqueId;
const SymbolType mSymbolType;
const TExtension mExtension;
};
......@@ -93,6 +104,7 @@ class TVariable : public TSymbol
TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED);
TType type;
......@@ -103,7 +115,10 @@ class TVariable : public TSymbol
class TStructure : public TSymbol, public TFieldListCollection
{
public:
TStructure(TSymbolTable *symbolTable, const TString *name, const TFieldList *fields);
TStructure(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
SymbolType symbolType);
bool isStruct() const override { return true; }
......@@ -135,6 +150,7 @@ class TInterfaceBlock : public TSymbol, public TFieldListCollection
const TString *name,
const TFieldList *fields,
const TLayoutQualifier &layoutQualifier,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
......@@ -191,9 +207,10 @@ class TFunction : public TSymbol
TFunction(TSymbolTable *symbolTable,
const TString *name,
const TType *retType,
SymbolType symbolType,
TOperator tOp = EOpNull,
TExtension extension = TExtension::UNDEFINED)
: TSymbol(symbolTable, name, extension),
: TSymbol(symbolTable, name, symbolType, extension),
returnType(retType),
mangledName(nullptr),
op(tOp),
......@@ -363,8 +380,8 @@ class TSymbolTable : angle::NonCopyable
bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
{
TVariable *constant =
new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1));
TVariable *constant = new TVariable(
this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
......@@ -378,7 +395,8 @@ class TSymbolTable : angle::NonCopyable
TPrecision precision)
{
TVariable *constant =
new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1), ext);
new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1),
SymbolType::BuiltIn, ext);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
......@@ -390,8 +408,8 @@ class TSymbolTable : angle::NonCopyable
const std::array<int, 3> &values,
TPrecision precision)
{
TVariable *constantIvec3 =
new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3));
TVariable *constantIvec3 = new TVariable(
this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[3];
for (size_t index = 0u; index < 3u; ++index)
......@@ -542,7 +560,10 @@ class TSymbolTable : angle::NonCopyable
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type);
TVariable *insertVariable(ESymbolLevel level,
const TString *name,
const TType &type,
SymbolType symbolType);
bool insert(ESymbolLevel level, TSymbol *symbol)
{
......
......@@ -429,7 +429,7 @@ int TType::getDeepestStructNesting() const
bool TType::isNamelessStruct() const
{
return mStructure && mStructure->name() == "";
return mStructure && mStructure->symbolType() == SymbolType::Empty;
}
bool TType::isStructureContainingArrays() const
......
......@@ -323,7 +323,7 @@ void UniformHLSL::outputUniform(TInfoSinkBase &out,
// TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
// nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers
// are permitted.
const TString &typeName = ((structure && !structure->name().empty())
const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty)
? QualifiedStructNameString(*structure, false, false)
: TypeString(type));
......
......@@ -692,7 +692,7 @@ TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat im
TString DecorateField(const TString &string, const TStructure &structure)
{
if (structure.name().compare(0, 3, "gl_") != 0)
if (structure.symbolType() != SymbolType::BuiltIn)
{
return Decorate(string);
}
......@@ -751,8 +751,7 @@ TString TypeString(const TType &type)
const TStructure *structure = type.getStruct();
if (structure)
{
const TString &typeName = structure->name();
if (typeName != "")
if (structure->symbolType() != SymbolType::Empty)
{
return StructNameString(*structure);
}
......@@ -847,7 +846,7 @@ TString TypeString(const TType &type)
TString StructNameString(const TStructure &structure)
{
if (structure.name().empty())
if (structure.symbolType() == SymbolType::Empty)
{
return "";
}
......@@ -866,7 +865,7 @@ TString QualifiedStructNameString(const TStructure &structure,
bool useHLSLRowMajorPacking,
bool useStd140Packing)
{
if (structure.name() == "")
if (structure.symbolType() == SymbolType::Empty)
{
return "";
}
......@@ -960,7 +959,7 @@ TString DisambiguateFunctionName(const TIntermSequence *parameters)
{
// Disambiguation is needed for struct parameters, since HLSL thinks that structs with
// the same fields but a different name are identical.
ASSERT(paramType.getStruct()->name() != "");
ASSERT(paramType.getStruct()->symbolType() != SymbolType::Empty);
disambiguatingString += "_" + TypeString(paramType);
}
}
......
......@@ -1206,7 +1206,7 @@ struct_specifier
$$ = context->addStructure(@1, @2, $2.string, $5);
}
| STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
$$ = context->addStructure(@1, @$, NewPoolTString(""), $4);
$$ = context->addStructure(@1, @$, nullptr, $4);
}
;
......
......@@ -4412,7 +4412,7 @@ yyreduce:
case 230:
{
(yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList));
(yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), nullptr, (yyvsp[-1].interm.fieldList));
}
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment