Define symbol classes in a separate file
The plan is to use symbols more also outside the symbol table, so it
makes sense to define the symbol classes in a separate header file.
BUG=angleproject:2267
TEST=angle_unittests
Change-Id: I94167415ef43ba9bd9126ca32d9c498e1437f3f8
Reviewed-on: https://chromium-review.googlesource.com/822414
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Symbol.cpp b/src/compiler/translator/Symbol.cpp
new file mode 100644
index 0000000..38a42b4
--- /dev/null
+++ b/src/compiler/translator/Symbol.cpp
@@ -0,0 +1,181 @@
+//
+// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Symbol.cpp: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/Symbol.h"
+
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+static const char kFunctionMangledNameSeparator = '(';
+
+} // anonymous namespace
+
+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);
+ ASSERT(mName != nullptr || mSymbolType == SymbolType::AngleInternal ||
+ mSymbolType == SymbolType::NotResolved || mSymbolType == SymbolType::Empty);
+}
+
+const TString *TSymbol::name() const
+{
+ if (mName != nullptr || mSymbolType == SymbolType::Empty)
+ {
+ return mName;
+ }
+ ASSERT(mSymbolType == SymbolType::AngleInternal);
+ TInfoSinkBase symbolNameOut;
+ symbolNameOut << "s" << mUniqueId.get();
+ return NewPoolTString(symbolNameOut.c_str());
+}
+
+const TString &TSymbol::getMangledName() const
+{
+ ASSERT(mSymbolType != SymbolType::Empty);
+ return *name();
+}
+
+TVariable::TVariable(TSymbolTable *symbolTable,
+ const TString *name,
+ const TType &t,
+ SymbolType symbolType,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
+{
+}
+
+TStructure::TStructure(TSymbolTable *symbolTable,
+ const TString *name,
+ const TFieldList *fields,
+ SymbolType symbolType)
+ : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
+{
+}
+
+void TStructure::createSamplerSymbols(const TString &namePrefix,
+ const TString &apiNamePrefix,
+ TVector<TIntermSymbol *> *outputSymbols,
+ TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const
+{
+ ASSERT(containsSamplers());
+ for (const auto *field : *mFields)
+ {
+ 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);
+ }
+ }
+}
+
+void TStructure::setName(const TString &name)
+{
+ TString *mutableName = const_cast<TString *>(mName);
+ *mutableName = name;
+}
+
+TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
+ const TString *name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, extension),
+ TFieldListCollection(fields),
+ mBlockStorage(layoutQualifier.blockStorage),
+ mBinding(layoutQualifier.binding)
+{
+ ASSERT(name != nullptr);
+}
+
+TFunction::TFunction(TSymbolTable *symbolTable,
+ const TString *name,
+ const TType *retType,
+ SymbolType symbolType,
+ TOperator tOp,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, extension),
+ returnType(retType),
+ mangledName(nullptr),
+ op(tOp),
+ defined(false),
+ mHasPrototypeDeclaration(false)
+{
+}
+
+//
+// Functions have buried pointers to delete.
+//
+TFunction::~TFunction()
+{
+ clearParameters();
+}
+
+void TFunction::clearParameters()
+{
+ for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
+ delete (*i).type;
+ parameters.clear();
+ mangledName = nullptr;
+}
+
+void TFunction::swapParameters(const TFunction ¶metersSource)
+{
+ clearParameters();
+ for (auto parameter : parametersSource.parameters)
+ {
+ addParameter(parameter);
+ }
+}
+
+const TString *TFunction::buildMangledName() const
+{
+ std::string newName = name()->c_str();
+ newName += kFunctionMangledNameSeparator;
+
+ for (const auto &p : parameters)
+ {
+ newName += p.type->getMangledName();
+ }
+ return NewPoolTString(newName.c_str());
+}
+
+const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
+ const TIntermSequence &arguments)
+{
+ std::string newName = functionName.c_str();
+ newName += kFunctionMangledNameSeparator;
+
+ for (TIntermNode *argument : arguments)
+ {
+ newName += argument->getAsTyped()->getType().getMangledName();
+ }
+ return *NewPoolTString(newName.c_str());
+}
+
+} // namespace sh