Commit d4529f30 by Olli Etuaho Committed by Commit Bot

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/822414Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent ffd27d85
...@@ -142,6 +142,8 @@ ...@@ -142,6 +142,8 @@
'compiler/translator/SplitSequenceOperator.h', 'compiler/translator/SplitSequenceOperator.h',
'compiler/translator/StaticType.cpp', 'compiler/translator/StaticType.cpp',
'compiler/translator/StaticType.h', 'compiler/translator/StaticType.h',
'compiler/translator/Symbol.cpp',
'compiler/translator/Symbol.h',
'compiler/translator/SymbolTable.cpp', 'compiler/translator/SymbolTable.cpp',
'compiler/translator/SymbolTable.h', 'compiler/translator/SymbolTable.h',
'compiler/translator/SymbolUniqueId.cpp', 'compiler/translator/SymbolUniqueId.cpp',
......
//
// 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 &parametersSource)
{
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
//
// 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.h: Symbols representing variables, functions, structures and interface blocks.
//
#ifndef COMPILER_TRANSLATOR_SYMBOL_H_
#define COMPILER_TRANSLATOR_SYMBOL_H_
#include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolUniqueId.h"
namespace sh
{
class TSymbolTable;
enum class SymbolType
{
BuiltIn,
UserDefined,
AngleInternal,
Empty, // Meaning symbol without a name.
NotResolved
};
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TSymbol(TSymbolTable *symbolTable,
const TString *name,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
virtual ~TSymbol()
{
// don't delete name, it's from the pool
}
const TString *name() const;
virtual const TString &getMangledName() const;
virtual bool isFunction() const { return false; }
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:
const TString *const mName;
private:
const TSymbolUniqueId mUniqueId;
const SymbolType mSymbolType;
const TExtension mExtension;
};
// Variable.
// May store the value of a constant variable of any type (float, int, bool or struct).
class TVariable : public TSymbol
{
public:
TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED);
~TVariable() override {}
bool isVariable() const override { return true; }
TType &getType() { return type; }
const TType &getType() const { return type; }
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
const TConstantUnion *getConstPointer() const { return unionArray; }
void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
private:
TType type;
const TConstantUnion *unionArray;
};
// Struct type.
class TStructure : public TSymbol, public TFieldListCollection
{
public:
TStructure(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
SymbolType symbolType);
bool isStruct() const override { return true; }
void createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols,
TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
TSymbolTable *symbolTable) const;
void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
bool atGlobalScope() const { return mAtGlobalScope; }
private:
// TODO(zmo): Find a way to get rid of the const_cast in function
// setName(). At the moment keep this function private so only
// friend class RegenerateStructNames may call it.
friend class RegenerateStructNames;
void setName(const TString &name);
bool mAtGlobalScope;
};
// Interface block. Note that this contains the block name, not the instance name. Interface block
// instances are stored as TVariable.
class TInterfaceBlock : public TSymbol, public TFieldListCollection
{
public:
TInterfaceBlock(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
const TLayoutQualifier &layoutQualifier,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
int blockBinding() const { return mBinding; }
private:
TLayoutBlockStorage mBlockStorage;
int mBinding;
// Note that we only record matrix packing on a per-field granularity.
};
// 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) {}
// 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;
const TString *const name;
const TType *const type;
};
// The function sub-class of symbols and the parser will need to
// share this definition of a function parameter.
struct TParameter
{
// Destructively converts to TConstParameter.
// This method resets name and type to nullptrs to make sure
// their content cannot be modified after the call.
TConstParameter turnToConst()
{
const TString *constName = name;
const TType *constType = type;
name = nullptr;
type = nullptr;
return TConstParameter(constName, constType);
}
const TString *name;
TType *type;
};
// The function sub-class of a symbol.
class TFunction : public TSymbol
{
public:
TFunction(TSymbolTable *symbolTable,
const TString *name,
const TType *retType,
SymbolType symbolType,
TOperator tOp = EOpNull,
TExtension extension = TExtension::UNDEFINED);
~TFunction() override;
bool isFunction() const override { return true; }
void addParameter(const TConstParameter &p)
{
parameters.push_back(p);
mangledName = nullptr;
}
void swapParameters(const TFunction &parametersSource);
const TString &getMangledName() const override
{
if (mangledName == nullptr)
{
mangledName = buildMangledName();
}
return *mangledName;
}
static const TString &GetMangledNameFromCall(const TString &functionName,
const TIntermSequence &arguments);
const TType &getReturnType() const { return *returnType; }
TOperator getBuiltInOp() const { return op; }
void setDefined() { defined = true; }
bool isDefined() { return defined; }
void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
size_t getParamCount() const { return parameters.size(); }
const TConstParameter &getParam(size_t i) const { return parameters[i]; }
private:
void clearParameters();
const TString *buildMangledName() const;
typedef TVector<TConstParameter> TParamList;
TParamList parameters;
const TType *returnType;
mutable const TString *mangledName;
TOperator op;
bool defined;
bool mHasPrototypeDeclaration;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_SYMBOL_H_
...@@ -22,152 +22,6 @@ ...@@ -22,152 +22,6 @@
namespace sh 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);
}
//
// 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 &parametersSource)
{
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());
}
// //
// Symbol table levels are a map of pointers to symbols that have to be deleted. // Symbol table levels are a map of pointers to symbols that have to be deleted.
// //
......
...@@ -38,235 +38,11 @@ ...@@ -38,235 +38,11 @@
#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolUniqueId.h" #include "compiler/translator/Symbol.h"
namespace sh namespace sh
{ {
enum class SymbolType
{
BuiltIn,
UserDefined,
AngleInternal,
Empty, // Meaning symbol without a name.
NotResolved
};
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TSymbol(TSymbolTable *symbolTable,
const TString *name,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
virtual ~TSymbol()
{
// don't delete name, it's from the pool
}
const TString *name() const;
virtual const TString &getMangledName() const;
virtual bool isFunction() const { return false; }
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:
const TString *const mName;
private:
const TSymbolUniqueId mUniqueId;
const SymbolType mSymbolType;
const TExtension mExtension;
};
// Variable.
// May store the value of a constant variable of any type (float, int, bool or struct).
class TVariable : public TSymbol
{
public:
TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED);
~TVariable() override {}
bool isVariable() const override { return true; }
TType &getType() { return type; }
const TType &getType() const { return type; }
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
const TConstantUnion *getConstPointer() const { return unionArray; }
void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
private:
TType type;
const TConstantUnion *unionArray;
};
// Struct type.
class TStructure : public TSymbol, public TFieldListCollection
{
public:
TStructure(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
SymbolType symbolType);
bool isStruct() const override { return true; }
void createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols,
TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
TSymbolTable *symbolTable) const;
void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
bool atGlobalScope() const { return mAtGlobalScope; }
private:
// TODO(zmo): Find a way to get rid of the const_cast in function
// setName(). At the moment keep this function private so only
// friend class RegenerateStructNames may call it.
friend class RegenerateStructNames;
void setName(const TString &name);
bool mAtGlobalScope;
};
// Interface block. Note that this contains the block name, not the instance name. Interface block
// instances are stored as TVariable.
class TInterfaceBlock : public TSymbol, public TFieldListCollection
{
public:
TInterfaceBlock(TSymbolTable *symbolTable,
const TString *name,
const TFieldList *fields,
const TLayoutQualifier &layoutQualifier,
SymbolType symbolType,
TExtension extension = TExtension::UNDEFINED);
TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
int blockBinding() const { return mBinding; }
private:
TLayoutBlockStorage mBlockStorage;
int mBinding;
// Note that we only record matrix packing on a per-field granularity.
};
// 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) {}
// 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;
const TString *const name;
const TType *const type;
};
// The function sub-class of symbols and the parser will need to
// share this definition of a function parameter.
struct TParameter
{
// Destructively converts to TConstParameter.
// This method resets name and type to nullptrs to make sure
// their content cannot be modified after the call.
TConstParameter turnToConst()
{
const TString *constName = name;
const TType *constType = type;
name = nullptr;
type = nullptr;
return TConstParameter(constName, constType);
}
const TString *name;
TType *type;
};
// The function sub-class of a symbol.
class TFunction : public TSymbol
{
public:
TFunction(TSymbolTable *symbolTable,
const TString *name,
const TType *retType,
SymbolType symbolType,
TOperator tOp = EOpNull,
TExtension extension = TExtension::UNDEFINED)
: TSymbol(symbolTable, name, symbolType, extension),
returnType(retType),
mangledName(nullptr),
op(tOp),
defined(false),
mHasPrototypeDeclaration(false)
{
}
~TFunction() override;
bool isFunction() const override { return true; }
void addParameter(const TConstParameter &p)
{
parameters.push_back(p);
mangledName = nullptr;
}
void swapParameters(const TFunction &parametersSource);
const TString &getMangledName() const override
{
if (mangledName == nullptr)
{
mangledName = buildMangledName();
}
return *mangledName;
}
static const TString &GetMangledNameFromCall(const TString &functionName,
const TIntermSequence &arguments);
const TType &getReturnType() const { return *returnType; }
TOperator getBuiltInOp() const { return op; }
void setDefined() { defined = true; }
bool isDefined() { return defined; }
void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
size_t getParamCount() const { return parameters.size(); }
const TConstParameter &getParam(size_t i) const { return parameters[i]; }
private:
void clearParameters();
const TString *buildMangledName() const;
typedef TVector<TConstParameter> TParamList;
TParamList parameters;
const TType *returnType;
mutable const TString *mangledName;
TOperator op;
bool defined;
bool mHasPrototypeDeclaration;
};
class TSymbolTableLevel class TSymbolTableLevel
{ {
public: public:
......
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