diff options
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp new file mode 100644 index 0000000000..fd5091c5ed --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp @@ -0,0 +1,179 @@ +// +// Copyright (c) 2018 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. +// +// FunctionLookup.cpp: Used for storing function calls that have not yet been resolved during +// parsing. +// + +#include "compiler/translator/FunctionLookup.h" +#include "compiler/translator/ImmutableStringBuilder.h" + +namespace sh +{ + +namespace +{ + +const char kFunctionMangledNameSeparator = '('; + +constexpr const ImmutableString kEmptyName(""); + +// Helper function for GetMangledNames +// Gets all ordered combinations of elements in list[currentIndex, end] +std::vector<std::vector<int>> GetImplicitConversionCombinations(const std::vector<int> &list) +{ + std::vector<std::vector<int>> target; + target.push_back(std::vector<int>()); + + for (size_t currentIndex = 0; currentIndex < list.size(); currentIndex++) + { + size_t prevIterSize = target.size(); + for (size_t copyIndex = 0; copyIndex < prevIterSize; copyIndex++) + { + std::vector<int> combination = target[copyIndex]; + combination.push_back(list[currentIndex]); + target.push_back(combination); + } + } + + return target; +} + +} // anonymous namespace + +TFunctionLookup::TFunctionLookup(const ImmutableString &name, + const TType *constructorType, + const TSymbol *symbol) + : mName(name), mConstructorType(constructorType), mThisNode(nullptr), mSymbol(symbol) +{} + +// static +TFunctionLookup *TFunctionLookup::CreateConstructor(const TType *type) +{ + ASSERT(type != nullptr); + return new TFunctionLookup(kEmptyName, type, nullptr); +} + +// static +TFunctionLookup *TFunctionLookup::CreateFunctionCall(const ImmutableString &name, + const TSymbol *symbol) +{ + ASSERT(name != ""); + return new TFunctionLookup(name, nullptr, symbol); +} + +const ImmutableString &TFunctionLookup::name() const +{ + return mName; +} + +ImmutableString TFunctionLookup::getMangledName() const +{ + return GetMangledName(mName.data(), mArguments); +} + +ImmutableString TFunctionLookup::GetMangledName(const char *functionName, + const TIntermSequence &arguments) +{ + std::string newName(functionName); + newName += kFunctionMangledNameSeparator; + + for (TIntermNode *argument : arguments) + { + newName += argument->getAsTyped()->getType().getMangledName(); + } + return ImmutableString(newName); +} + +std::vector<ImmutableString> GetMangledNames(const char *functionName, + const TIntermSequence &arguments) +{ + std::vector<ImmutableString> target; + + std::vector<int> indexes; + for (int i = 0; i < static_cast<int>(arguments.size()); i++) + { + TIntermNode *argument = arguments[i]; + TBasicType argType = argument->getAsTyped()->getType().getBasicType(); + if (argType == EbtInt || argType == EbtUInt) + { + indexes.push_back(i); + } + } + + std::vector<std::vector<int>> combinations = GetImplicitConversionCombinations(indexes); + for (const std::vector<int> &combination : combinations) + { + // combination: ordered list of indexes for arguments that should be converted to float + std::string newName(functionName); + newName += kFunctionMangledNameSeparator; + // combination[currentIndex] represents index of next argument to be converted + int currentIndex = 0; + for (int i = 0; i < (int)arguments.size(); i++) + { + TIntermNode *argument = arguments[i]; + + if (currentIndex != static_cast<int>(combination.size()) && + combination[currentIndex] == i) + { + // Convert + TType type = argument->getAsTyped()->getType(); + type.setBasicType(EbtFloat); + newName += type.getMangledName(); + currentIndex++; + } + else + { + // Don't convert + newName += argument->getAsTyped()->getType().getMangledName(); + } + } + target.push_back(ImmutableString(newName)); + } + + return target; +} + +std::vector<ImmutableString> TFunctionLookup::getMangledNamesForImplicitConversions() const +{ + return GetMangledNames(mName.data(), mArguments); +} + +bool TFunctionLookup::isConstructor() const +{ + return mConstructorType != nullptr; +} + +const TType &TFunctionLookup::constructorType() const +{ + return *mConstructorType; +} + +void TFunctionLookup::setThisNode(TIntermTyped *thisNode) +{ + mThisNode = thisNode; +} + +TIntermTyped *TFunctionLookup::thisNode() const +{ + return mThisNode; +} + +void TFunctionLookup::addArgument(TIntermTyped *argument) +{ + mArguments.push_back(argument); +} + +TIntermSequence &TFunctionLookup::arguments() +{ + return mArguments; +} + +const TSymbol *TFunctionLookup::symbol() const +{ + return mSymbol; +} + +} // namespace sh |