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/923987
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
index 5111aaa..b981f8b 100644
--- a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -127,8 +127,8 @@
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));
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index 1704d41..0e14054 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -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 @@
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);
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index f2714b0..268a4a4 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -715,8 +715,8 @@
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)
{
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 06cd1c8..474fdc4 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -3429,7 +3429,7 @@
}
// 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,
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index 155e3d1..2b77ab3 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -406,8 +406,8 @@
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 @@
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));
diff --git a/src/compiler/translator/RunAtTheEndOfShader.cpp b/src/compiler/translator/RunAtTheEndOfShader.cpp
index ca82a07..9a6f8d6 100644
--- a/src/compiler/translator/RunAtTheEndOfShader.cpp
+++ b/src/compiler/translator/RunAtTheEndOfShader.cpp
@@ -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 @@
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 @@
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);
// {
diff --git a/src/compiler/translator/Symbol.cpp b/src/compiler/translator/Symbol.cpp
index daaa33f..3e7b83a 100644
--- a/src/compiler/translator/Symbol.cpp
+++ b/src/compiler/translator/Symbol.cpp
@@ -126,37 +126,66 @@
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 ¶metersSource)
+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 ¶metersSource)
+{
+ mParametersVector = nullptr;
+ mParameters = parametersSource.mParameters;
+ mParamCount = parametersSource.mParamCount;
+ ASSERT(parametersSource.name() == name());
+ mMangledName = parametersSource.mMangledName;
}
ImmutableString TFunction::buildMangledName() const
@@ -164,9 +193,9 @@
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);
}
diff --git a/src/compiler/translator/Symbol.h b/src/compiler/translator/Symbol.h
index 0322cbe..cc5a81a 100644
--- a/src/compiler/translator/Symbol.h
+++ b/src/compiler/translator/Symbol.h
@@ -159,9 +159,10 @@
// 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 @@
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);
+
+ // Built-in function
+ TFunction(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ TExtension extension,
+ TConstParameter *parameters,
+ size_t paramCount,
+ const TType *retType,
+ TOperator op,
+ bool knownToNotHaveSideEffects);
bool isFunction() const override { return true; }
- void addParameter(const TConstParameter &p)
- {
- parameters.push_back(p);
- mangledName = ImmutableString("");
- }
-
- void swapParameters(const TFunction ¶metersSource);
+ void addParameter(const TConstParameter &p);
+ void shareParameters(const TFunction ¶metersSource);
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 @@
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;
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 49b49fc..a4110ce 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -174,9 +174,9 @@
// 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 @@
}
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 @@
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 @@
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)