| // |
| // Copyright 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 |