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
new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType,
SymbolType::AngleInternal);
TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(),
StaticType::GetBasic<EbtVoid>(),
node->getFunction()->symbolType(), false);
node->getFunction()->symbolType(),
StaticType::GetBasic<EbtVoid>(), false);
for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
{
func->addParameter(node->getFunction()->getParam(i));
......
......@@ -22,6 +22,7 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/ReplaceVariable.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
......@@ -104,8 +105,9 @@ void InsertInitCallToMain(TIntermBlock *root,
TIntermBlock *initGlobalsBlock = new TIntermBlock();
initGlobalsBlock->getSequence()->swap(*deferredInitializers);
TFunction *initGlobalsFunction = new TFunction(
symbolTable, kInitGlobalsString, new TType(EbtVoid), SymbolType::AngleInternal, false);
TFunction *initGlobalsFunction =
new TFunction(symbolTable, kInitGlobalsString, SymbolType::AngleInternal,
StaticType::GetBasic<EbtVoid>(), false);
TIntermFunctionPrototype *initGlobalsFunctionPrototype =
CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
......
......@@ -715,8 +715,8 @@ const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &fu
ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
{
TFunction *func = new TFunction(mSymbolTable, functionName, new TType(returnType),
SymbolType::AngleInternal, knownToNotHaveSideEffects);
TFunction *func = new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
new TType(returnType), knownToNotHaveSideEffects);
ASSERT(parameters.size() == arguments->size());
for (size_t i = 0; i < parameters.size(); ++i)
{
......
......@@ -3429,7 +3429,7 @@ 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), SymbolType::UserDefined, false);
return new TFunction(&symbolTable, name, SymbolType::UserDefined, new TType(type), false);
}
TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name,
......
......@@ -406,8 +406,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
{
indexingFunction =
new TFunction(mSymbolTable, indexingFunctionName, GetFieldType(type),
SymbolType::AngleInternal, true);
new TFunction(mSymbolTable, indexingFunctionName, SymbolType::AngleInternal,
GetFieldType(type), true);
indexingFunction->addParameter(
TConstParameter(kBaseName, GetBaseType(type, false)));
indexingFunction->addParameter(TConstParameter(kIndexName, kIndexType));
......@@ -456,8 +456,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
ImmutableString functionName(
GetIndexFunctionName(node->getLeft()->getType(), true));
indexedWriteFunction =
new TFunction(mSymbolTable, functionName, StaticType::GetBasic<EbtVoid>(),
SymbolType::AngleInternal, false);
new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
StaticType::GetBasic<EbtVoid>(), false);
indexedWriteFunction->addParameter(
TConstParameter(kBaseName, GetBaseType(type, true)));
indexedWriteFunction->addParameter(TConstParameter(kIndexName, kIndexType));
......
......@@ -25,6 +25,7 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
......@@ -68,8 +69,8 @@ void WrapMainAndAppend(TIntermBlock *root,
TSymbolTable *symbolTable)
{
// Replace main() with main0() with the same body.
TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), new TType(EbtVoid),
SymbolType::AngleInternal, false);
TFunction *oldMain = new TFunction(symbolTable, ImmutableString(""), SymbolType::AngleInternal,
StaticType::GetBasic<EbtVoid>(), false);
TIntermFunctionDefinition *oldMainDefinition =
CreateInternalFunctionDefinitionNode(*oldMain, main->getBody());
......@@ -77,8 +78,8 @@ void WrapMainAndAppend(TIntermBlock *root,
ASSERT(replaced);
// void main()
TFunction *newMain =
new TFunction(symbolTable, kMainString, new TType(EbtVoid), SymbolType::UserDefined, false);
TFunction *newMain = new TFunction(symbolTable, kMainString, SymbolType::UserDefined,
StaticType::GetBasic<EbtVoid>(), false);
TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
// {
......
......@@ -126,37 +126,66 @@ TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
TFunction::TFunction(TSymbolTable *symbolTable,
const ImmutableString &name,
const TType *retType,
SymbolType symbolType,
bool knownToNotHaveSideEffects,
TOperator tOp,
TExtension extension)
: TSymbol(symbolTable, name, symbolType, extension),
const TType *retType,
bool knownToNotHaveSideEffects)
: TSymbol(symbolTable, name, symbolType, TExtension::UNDEFINED),
mParametersVector(new TParamVector()),
mParameters(nullptr),
mParamCount(0u),
returnType(retType),
mangledName(nullptr),
op(tOp),
mMangledName(""),
mOp(EOpNull),
defined(false),
mHasPrototypeDeclaration(false),
mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
{
// Functions with an empty name are not allowed.
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();
mangledName = ImmutableString("");
ASSERT(name != nullptr);
ASSERT(op != EOpNull);
ASSERT(paramCount == 0 || parameters != nullptr);
mMangledName = buildMangledName();
}
void TFunction::swapParameters(const TFunction &parametersSource)
void TFunction::addParameter(const TConstParameter &p)
{
clearParameters();
for (auto parameter : parametersSource.parameters)
{
addParameter(parameter);
}
ASSERT(mParametersVector);
mParametersVector->push_back(p);
mParameters = mParametersVector->data();
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
......@@ -164,9 +193,9 @@ ImmutableString TFunction::buildMangledName() const
std::string newName(name().data(), name().length());
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);
}
......
......@@ -159,9 +159,10 @@ class TInterfaceBlock : public TSymbol, public TFieldListCollection
// Immutable version of TParameter.
struct TConstParameter
{
POOL_ALLOCATOR_NEW_DELETE();
TConstParameter() : name(""), 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) {}
// Both constructor arguments must be const.
......@@ -197,44 +198,48 @@ struct TParameter
class TFunction : public TSymbol
{
public:
// User-defined function
TFunction(TSymbolTable *symbolTable,
const ImmutableString &name,
const TType *retType,
SymbolType symbolType,
bool knownToNotHaveSideEffects,
TOperator tOp = EOpNull,
TExtension extension = TExtension::UNDEFINED);
const TType *retType,
bool knownToNotHaveSideEffects);
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)
{
parameters.push_back(p);
mangledName = ImmutableString("");
}
bool isFunction() const override { return true; }
void swapParameters(const TFunction &parametersSource);
void addParameter(const TConstParameter &p);
void shareParameters(const TFunction &parametersSource);
ImmutableString getMangledName() const override
{
if (mangledName == "")
if (mMangledName == "")
{
mangledName = buildMangledName();
mMangledName = buildMangledName();
}
return mangledName;
return mMangledName;
}
const TType &getReturnType() const { return *returnType; }
TOperator getBuiltInOp() const { return op; }
TOperator getBuiltInOp() const { return mOp; }
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]; }
size_t getParamCount() const { return mParamCount; }
const TConstParameter &getParam(size_t i) const { return mParameters[i]; }
bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
......@@ -242,15 +247,37 @@ class TFunction : public TSymbol
bool isImageFunction() const;
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;
typedef TVector<TConstParameter> TParamList;
TParamList parameters;
typedef TVector<TConstParameter> TParamVector;
TParamVector *mParametersVector;
const TConstParameter *mParameters;
size_t mParamCount;
const TType *const returnType;
mutable ImmutableString mangledName;
const TOperator op; // Only set for built-ins
mutable ImmutableString mMangledName;
const TOperator mOp; // Only set for built-ins
bool defined;
bool mHasPrototypeDeclaration;
bool mKnownToNotHaveSideEffects;
......
......@@ -174,9 +174,9 @@ const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinitio
// occurance.
if (function != firstDeclaration)
{
// Swap the parameters of the previous declaration to the parameters of the function
// definition (parameter names may differ).
firstDeclaration->swapParameters(*function);
// The previous declaration should have the same parameters as the function definition
// (parameter names may differ).
firstDeclaration->shareParameters(*function);
}
*wasDefinedOut = firstDeclaration->isDefined();
......@@ -591,30 +591,32 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
}
else
{
TFunction *function =
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
function->addParameter(TConstParameter(ptype1));
size_t paramCount = 1;
TConstParameter *params = new TConstParameter[5];
new (params) TConstParameter(ptype1);
if (ptype2)
{
function->addParameter(TConstParameter(ptype2));
new (params + 1) TConstParameter(ptype2);
paramCount = 2;
}
if (ptype3)
{
function->addParameter(TConstParameter(ptype3));
new (params + 2) TConstParameter(ptype3);
paramCount = 3;
}
if (ptype4)
{
function->addParameter(TConstParameter(ptype4));
new (params + 3) TConstParameter(ptype4);
paramCount = 4;
}
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));
insert(level, function);
......@@ -658,8 +660,8 @@ void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
const char *name)
{
insertUnmangledBuiltInName(name, level);
insert(level,
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op));
insert(level, new TFunction(this, ImmutableString(name), TExtension::UNDEFINED, nullptr, 0,
rvalue, op, false));
}
void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
......@@ -669,8 +671,7 @@ void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
const char *name)
{
insertUnmangledBuiltInName(name, level);
insert(level,
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
insert(level, new TFunction(this, ImmutableString(name), ext, nullptr, 0, rvalue, op, false));
}
void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec)
......
......@@ -65,8 +65,8 @@ class IntermNodeTest : public testing::Test
// We're using a dummy symbol table similarly as for creating symbol nodes.
const ImmutableString name("testFunc");
TSymbolTable symbolTable;
TFunction *func = new TFunction(&symbolTable, name, new TType(returnType),
SymbolType::UserDefined, false);
TFunction *func = new TFunction(&symbolTable, name, SymbolType::UserDefined,
new TType(returnType), false);
for (TIntermNode *arg : args)
{
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