Commit 029e8ca7 by Olli Etuaho Committed by Commit Bot

Add a constexpr constructor for TFunction

Access to TFunction parameters is now handled through two new members: a pointer to a parameter array and a parameter count. There's still also a vector pointer in TFunction for adding function parameters one by one. This is used when parsing user-defined functions. TEST=angle_unittests BUG=angleproject:2267 Change-Id: I86987ae56b7cf37f010d0651e9861789050aec2b Reviewed-on: https://chromium-review.googlesource.com/923987Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 697bf65c
...@@ -127,8 +127,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit ...@@ -127,8 +127,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit
new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType, new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType,
SymbolType::AngleInternal); SymbolType::AngleInternal);
TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(), TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(),
StaticType::GetBasic<EbtVoid>(), node->getFunction()->symbolType(),
node->getFunction()->symbolType(), false); StaticType::GetBasic<EbtVoid>(), false);
for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i) for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
{ {
func->addParameter(node->getFunction()->getParam(i)); func->addParameter(node->getFunction()->getParam(i));
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/ReplaceVariable.h" #include "compiler/translator/ReplaceVariable.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
namespace sh namespace sh
...@@ -104,8 +105,9 @@ void InsertInitCallToMain(TIntermBlock *root, ...@@ -104,8 +105,9 @@ void InsertInitCallToMain(TIntermBlock *root,
TIntermBlock *initGlobalsBlock = new TIntermBlock(); TIntermBlock *initGlobalsBlock = new TIntermBlock();
initGlobalsBlock->getSequence()->swap(*deferredInitializers); initGlobalsBlock->getSequence()->swap(*deferredInitializers);
TFunction *initGlobalsFunction = new TFunction( TFunction *initGlobalsFunction =
symbolTable, kInitGlobalsString, new TType(EbtVoid), SymbolType::AngleInternal, false); new TFunction(symbolTable, kInitGlobalsString, SymbolType::AngleInternal,
StaticType::GetBasic<EbtVoid>(), false);
TIntermFunctionPrototype *initGlobalsFunctionPrototype = TIntermFunctionPrototype *initGlobalsFunctionPrototype =
CreateInternalFunctionPrototypeNode(*initGlobalsFunction); CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
......
...@@ -715,8 +715,8 @@ const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &fu ...@@ -715,8 +715,8 @@ const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &fu
ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments); ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
if (mInternalFunctions.find(mangledName) == mInternalFunctions.end()) if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
{ {
TFunction *func = new TFunction(mSymbolTable, functionName, new TType(returnType), TFunction *func = new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
SymbolType::AngleInternal, knownToNotHaveSideEffects); new TType(returnType), knownToNotHaveSideEffects);
ASSERT(parameters.size() == arguments->size()); ASSERT(parameters.size() == arguments->size());
for (size_t i = 0; i < parameters.size(); ++i) for (size_t i = 0; i < parameters.size(); ++i)
{ {
......
...@@ -3429,7 +3429,7 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, ...@@ -3429,7 +3429,7 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
} }
// Add the function as a prototype after parsing it (we do not support recursion) // Add the function as a prototype after parsing it (we do not support recursion)
return new TFunction(&symbolTable, name, new TType(type), SymbolType::UserDefined, false); return new TFunction(&symbolTable, name, SymbolType::UserDefined, new TType(type), false);
} }
TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name, TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name,
......
...@@ -406,8 +406,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod ...@@ -406,8 +406,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end()) if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
{ {
indexingFunction = indexingFunction =
new TFunction(mSymbolTable, indexingFunctionName, GetFieldType(type), new TFunction(mSymbolTable, indexingFunctionName, SymbolType::AngleInternal,
SymbolType::AngleInternal, true); GetFieldType(type), true);
indexingFunction->addParameter( indexingFunction->addParameter(
TConstParameter(kBaseName, GetBaseType(type, false))); TConstParameter(kBaseName, GetBaseType(type, false)));
indexingFunction->addParameter(TConstParameter(kIndexName, kIndexType)); indexingFunction->addParameter(TConstParameter(kIndexName, kIndexType));
...@@ -456,8 +456,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod ...@@ -456,8 +456,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
ImmutableString functionName( ImmutableString functionName(
GetIndexFunctionName(node->getLeft()->getType(), true)); GetIndexFunctionName(node->getLeft()->getType(), true));
indexedWriteFunction = indexedWriteFunction =
new TFunction(mSymbolTable, functionName, StaticType::GetBasic<EbtVoid>(), new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
SymbolType::AngleInternal, false); StaticType::GetBasic<EbtVoid>(), false);
indexedWriteFunction->addParameter( indexedWriteFunction->addParameter(
TConstParameter(kBaseName, GetBaseType(type, true))); TConstParameter(kBaseName, GetBaseType(type, true)));
indexedWriteFunction->addParameter(TConstParameter(kIndexName, kIndexType)); indexedWriteFunction->addParameter(TConstParameter(kIndexName, kIndexType));
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
namespace sh namespace sh
...@@ -68,8 +69,8 @@ void WrapMainAndAppend(TIntermBlock *root, ...@@ -68,8 +69,8 @@ void WrapMainAndAppend(TIntermBlock *root,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
// Replace main() with main0() with the same body. // Replace main() with main0() with the same body.
TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), new TType(EbtVoid), TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), SymbolType::AngleInternal,
SymbolType::AngleInternal, false); StaticType::GetBasic<EbtVoid>(), false);
TIntermFunctionDefinition *oldMainDefinition = TIntermFunctionDefinition *oldMainDefinition =
CreateInternalFunctionDefinitionNode(*oldMain, main->getBody()); CreateInternalFunctionDefinitionNode(*oldMain, main->getBody());
...@@ -77,8 +78,8 @@ void WrapMainAndAppend(TIntermBlock *root, ...@@ -77,8 +78,8 @@ void WrapMainAndAppend(TIntermBlock *root,
ASSERT(replaced); ASSERT(replaced);
// void main() // void main()
TFunction *newMain = TFunction *newMain = new TFunction(symbolTable, kMainString, SymbolType::UserDefined,
new TFunction(symbolTable, kMainString, new TType(EbtVoid), SymbolType::UserDefined, false); StaticType::GetBasic<EbtVoid>(), false);
TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain); TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
// { // {
......
...@@ -126,37 +126,66 @@ TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable, ...@@ -126,37 +126,66 @@ TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
TFunction::TFunction(TSymbolTable *symbolTable, TFunction::TFunction(TSymbolTable *symbolTable,
const ImmutableString &name, const ImmutableString &name,
const TType *retType,
SymbolType symbolType, SymbolType symbolType,
bool knownToNotHaveSideEffects, const TType *retType,
TOperator tOp, bool knownToNotHaveSideEffects)
TExtension extension) : TSymbol(symbolTable, name, symbolType, TExtension::UNDEFINED),
: TSymbol(symbolTable, name, symbolType, extension), mParametersVector(new TParamVector()),
mParameters(nullptr),
mParamCount(0u),
returnType(retType), returnType(retType),
mangledName(nullptr), mMangledName(""),
op(tOp), mOp(EOpNull),
defined(false), defined(false),
mHasPrototypeDeclaration(false), mHasPrototypeDeclaration(false),
mKnownToNotHaveSideEffects(knownToNotHaveSideEffects) mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
{ {
// Functions with an empty name are not allowed. // Functions with an empty name are not allowed.
ASSERT(symbolType != SymbolType::Empty); ASSERT(symbolType != SymbolType::Empty);
ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal || tOp != EOpNull); ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
} }
void TFunction::clearParameters() TFunction::TFunction(TSymbolTable *symbolTable,
const ImmutableString &name,
TExtension extension,
TConstParameter *parameters,
size_t paramCount,
const TType *retType,
TOperator op,
bool knownToNotHaveSideEffects)
: TSymbol(symbolTable, name, SymbolType::BuiltIn, extension),
mParametersVector(nullptr),
mParameters(parameters),
mParamCount(paramCount),
returnType(retType),
mMangledName(""),
mOp(op),
defined(false),
mHasPrototypeDeclaration(false),
mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
{ {
parameters.clear(); ASSERT(name != nullptr);
mangledName = ImmutableString(""); ASSERT(op != EOpNull);
ASSERT(paramCount == 0 || parameters != nullptr);
mMangledName = buildMangledName();
} }
void TFunction::swapParameters(const TFunction &parametersSource) void TFunction::addParameter(const TConstParameter &p)
{ {
clearParameters(); ASSERT(mParametersVector);
for (auto parameter : parametersSource.parameters) mParametersVector->push_back(p);
{ mParameters = mParametersVector->data();
addParameter(parameter); mParamCount = mParametersVector->size();
} mMangledName = ImmutableString("");
}
void TFunction::shareParameters(const TFunction &parametersSource)
{
mParametersVector = nullptr;
mParameters = parametersSource.mParameters;
mParamCount = parametersSource.mParamCount;
ASSERT(parametersSource.name() == name());
mMangledName = parametersSource.mMangledName;
} }
ImmutableString TFunction::buildMangledName() const ImmutableString TFunction::buildMangledName() const
...@@ -164,9 +193,9 @@ ImmutableString TFunction::buildMangledName() const ...@@ -164,9 +193,9 @@ ImmutableString TFunction::buildMangledName() const
std::string newName(name().data(), name().length()); std::string newName(name().data(), name().length());
newName += kFunctionMangledNameSeparator; newName += kFunctionMangledNameSeparator;
for (const auto &p : parameters) for (size_t i = 0u; i < mParamCount; ++i)
{ {
newName += p.type->getMangledName(); newName += mParameters[i].type->getMangledName();
} }
return ImmutableString(newName); return ImmutableString(newName);
} }
......
...@@ -159,9 +159,10 @@ class TInterfaceBlock : public TSymbol, public TFieldListCollection ...@@ -159,9 +159,10 @@ class TInterfaceBlock : public TSymbol, public TFieldListCollection
// Immutable version of TParameter. // Immutable version of TParameter.
struct TConstParameter struct TConstParameter
{ {
POOL_ALLOCATOR_NEW_DELETE();
TConstParameter() : name(""), type(nullptr) {} TConstParameter() : name(""), type(nullptr) {}
explicit TConstParameter(const ImmutableString &n) : name(n), type(nullptr) {} explicit TConstParameter(const ImmutableString &n) : name(n), type(nullptr) {}
explicit TConstParameter(const TType *t) : name(""), type(t) {} constexpr explicit TConstParameter(const TType *t) : name(""), type(t) {}
TConstParameter(const ImmutableString &n, const TType *t) : name(n), type(t) {} TConstParameter(const ImmutableString &n, const TType *t) : name(n), type(t) {}
// Both constructor arguments must be const. // Both constructor arguments must be const.
...@@ -197,44 +198,48 @@ struct TParameter ...@@ -197,44 +198,48 @@ struct TParameter
class TFunction : public TSymbol class TFunction : public TSymbol
{ {
public: public:
// User-defined function
TFunction(TSymbolTable *symbolTable, TFunction(TSymbolTable *symbolTable,
const ImmutableString &name, const ImmutableString &name,
const TType *retType,
SymbolType symbolType, SymbolType symbolType,
bool knownToNotHaveSideEffects, const TType *retType,
TOperator tOp = EOpNull, bool knownToNotHaveSideEffects);
TExtension extension = TExtension::UNDEFINED);
bool isFunction() const override { return true; } // Built-in function
TFunction(TSymbolTable *symbolTable,
const ImmutableString &name,
TExtension extension,
TConstParameter *parameters,
size_t paramCount,
const TType *retType,
TOperator op,
bool knownToNotHaveSideEffects);
void addParameter(const TConstParameter &p) bool isFunction() const override { return true; }
{
parameters.push_back(p);
mangledName = ImmutableString("");
}
void swapParameters(const TFunction &parametersSource); void addParameter(const TConstParameter &p);
void shareParameters(const TFunction &parametersSource);
ImmutableString getMangledName() const override ImmutableString getMangledName() const override
{ {
if (mangledName == "") if (mMangledName == "")
{ {
mangledName = buildMangledName(); mMangledName = buildMangledName();
} }
return mangledName; return mMangledName;
} }
const TType &getReturnType() const { return *returnType; } const TType &getReturnType() const { return *returnType; }
TOperator getBuiltInOp() const { return op; } TOperator getBuiltInOp() const { return mOp; }
void setDefined() { defined = true; } void setDefined() { defined = true; }
bool isDefined() { return defined; } bool isDefined() { return defined; }
void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; } void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; } bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
size_t getParamCount() const { return parameters.size(); } size_t getParamCount() const { return mParamCount; }
const TConstParameter &getParam(size_t i) const { return parameters[i]; } const TConstParameter &getParam(size_t i) const { return mParameters[i]; }
bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; } bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
...@@ -242,15 +247,37 @@ class TFunction : public TSymbol ...@@ -242,15 +247,37 @@ class TFunction : public TSymbol
bool isImageFunction() const; bool isImageFunction() const;
private: private:
void clearParameters(); constexpr TFunction(const TSymbolUniqueId &id,
const ImmutableString &name,
TExtension extension,
const TConstParameter *parameters,
size_t paramCount,
const TType *retType,
const ImmutableString &mangledName,
TOperator op,
bool knownToNotHaveSideEffects)
: TSymbol(id, name, SymbolType::BuiltIn, extension),
mParametersVector(nullptr),
mParameters(parameters),
mParamCount(paramCount),
returnType(retType),
mMangledName(mangledName),
mOp(op),
defined(false),
mHasPrototypeDeclaration(false),
mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
{
}
ImmutableString buildMangledName() const; ImmutableString buildMangledName() const;
typedef TVector<TConstParameter> TParamList; typedef TVector<TConstParameter> TParamVector;
TParamList parameters; TParamVector *mParametersVector;
const TConstParameter *mParameters;
size_t mParamCount;
const TType *const returnType; const TType *const returnType;
mutable ImmutableString mangledName; mutable ImmutableString mMangledName;
const TOperator op; // Only set for built-ins const TOperator mOp; // Only set for built-ins
bool defined; bool defined;
bool mHasPrototypeDeclaration; bool mHasPrototypeDeclaration;
bool mKnownToNotHaveSideEffects; bool mKnownToNotHaveSideEffects;
......
...@@ -174,9 +174,9 @@ const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinitio ...@@ -174,9 +174,9 @@ const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinitio
// occurance. // occurance.
if (function != firstDeclaration) if (function != firstDeclaration)
{ {
// Swap the parameters of the previous declaration to the parameters of the function // The previous declaration should have the same parameters as the function definition
// definition (parameter names may differ). // (parameter names may differ).
firstDeclaration->swapParameters(*function); firstDeclaration->shareParameters(*function);
} }
*wasDefinedOut = firstDeclaration->isDefined(); *wasDefinedOut = firstDeclaration->isDefined();
...@@ -591,30 +591,32 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -591,30 +591,32 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
} }
else else
{ {
TFunction *function = size_t paramCount = 1;
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext); TConstParameter *params = new TConstParameter[5];
new (params) TConstParameter(ptype1);
function->addParameter(TConstParameter(ptype1));
if (ptype2) if (ptype2)
{ {
function->addParameter(TConstParameter(ptype2)); new (params + 1) TConstParameter(ptype2);
paramCount = 2;
} }
if (ptype3) if (ptype3)
{ {
function->addParameter(TConstParameter(ptype3)); new (params + 2) TConstParameter(ptype3);
paramCount = 3;
} }
if (ptype4) if (ptype4)
{ {
function->addParameter(TConstParameter(ptype4)); new (params + 3) TConstParameter(ptype4);
paramCount = 4;
} }
if (ptype5) if (ptype5)
{ {
function->addParameter(TConstParameter(ptype5)); new (params + 4) TConstParameter(ptype5);
paramCount = 5;
} }
TFunction *function =
new TFunction(this, ImmutableString(name), ext, params, paramCount, rvalue, op, false);
ASSERT(hasUnmangledBuiltInAtLevel(name, level)); ASSERT(hasUnmangledBuiltInAtLevel(name, level));
insert(level, function); insert(level, function);
...@@ -658,8 +660,8 @@ void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level, ...@@ -658,8 +660,8 @@ void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
const char *name) const char *name)
{ {
insertUnmangledBuiltInName(name, level); insertUnmangledBuiltInName(name, level);
insert(level, insert(level, new TFunction(this, ImmutableString(name), TExtension::UNDEFINED, nullptr, 0,
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op)); rvalue, op, false));
} }
void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level, void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
...@@ -669,8 +671,7 @@ void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level, ...@@ -669,8 +671,7 @@ void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
const char *name) const char *name)
{ {
insertUnmangledBuiltInName(name, level); insertUnmangledBuiltInName(name, level);
insert(level, insert(level, new TFunction(this, ImmutableString(name), ext, nullptr, 0, rvalue, op, false));
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
} }
void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec) void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec)
......
...@@ -65,8 +65,8 @@ class IntermNodeTest : public testing::Test ...@@ -65,8 +65,8 @@ class IntermNodeTest : public testing::Test
// We're using a dummy symbol table similarly as for creating symbol nodes. // We're using a dummy symbol table similarly as for creating symbol nodes.
const ImmutableString name("testFunc"); const ImmutableString name("testFunc");
TSymbolTable symbolTable; TSymbolTable symbolTable;
TFunction *func = new TFunction(&symbolTable, name, new TType(returnType), TFunction *func = new TFunction(&symbolTable, name, SymbolType::UserDefined,
SymbolType::UserDefined, false); new TType(returnType), false);
for (TIntermNode *arg : args) for (TIntermNode *arg : args)
{ {
const TType *type = new TType(arg->getAsTyped()->getType()); const TType *type = new TType(arg->getAsTyped()->getType());
......
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