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