FunctionLookup.cpp (5042B)
1 // 2 // Copyright 2018 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // FunctionLookup.cpp: Used for storing function calls that have not yet been resolved during 7 // parsing. 8 // 9 10 #include "compiler/translator/FunctionLookup.h" 11 #include "compiler/translator/ImmutableStringBuilder.h" 12 13 namespace sh 14 { 15 16 namespace 17 { 18 19 const char kFunctionMangledNameSeparator = '('; 20 21 constexpr const ImmutableString kEmptyName(""); 22 23 // Helper function for GetMangledNames 24 // Gets all ordered combinations of elements in list[currentIndex, end] 25 std::vector<std::vector<int>> GetImplicitConversionCombinations(const std::vector<int> &list) 26 { 27 std::vector<std::vector<int>> target; 28 target.push_back(std::vector<int>()); 29 30 for (size_t currentIndex = 0; currentIndex < list.size(); currentIndex++) 31 { 32 size_t prevIterSize = target.size(); 33 for (size_t copyIndex = 0; copyIndex < prevIterSize; copyIndex++) 34 { 35 std::vector<int> combination = target[copyIndex]; 36 combination.push_back(list[currentIndex]); 37 target.push_back(combination); 38 } 39 } 40 41 return target; 42 } 43 44 } // anonymous namespace 45 46 TFunctionLookup::TFunctionLookup(const ImmutableString &name, 47 const TType *constructorType, 48 const TSymbol *symbol) 49 : mName(name), mConstructorType(constructorType), mThisNode(nullptr), mSymbol(symbol) 50 {} 51 52 // static 53 TFunctionLookup *TFunctionLookup::CreateConstructor(const TType *type) 54 { 55 ASSERT(type != nullptr); 56 return new TFunctionLookup(kEmptyName, type, nullptr); 57 } 58 59 // static 60 TFunctionLookup *TFunctionLookup::CreateFunctionCall(const ImmutableString &name, 61 const TSymbol *symbol) 62 { 63 ASSERT(name != ""); 64 return new TFunctionLookup(name, nullptr, symbol); 65 } 66 67 const ImmutableString &TFunctionLookup::name() const 68 { 69 return mName; 70 } 71 72 ImmutableString TFunctionLookup::getMangledName() const 73 { 74 return GetMangledName(mName.data(), mArguments); 75 } 76 77 ImmutableString TFunctionLookup::GetMangledName(const char *functionName, 78 const TIntermSequence &arguments) 79 { 80 std::string newName(functionName); 81 newName += kFunctionMangledNameSeparator; 82 83 for (TIntermNode *argument : arguments) 84 { 85 newName += argument->getAsTyped()->getType().getMangledName(); 86 } 87 return ImmutableString(newName); 88 } 89 90 std::vector<ImmutableString> GetMangledNames(const char *functionName, 91 const TIntermSequence &arguments) 92 { 93 std::vector<ImmutableString> target; 94 95 std::vector<int> indexes; 96 for (int i = 0; i < static_cast<int>(arguments.size()); i++) 97 { 98 TIntermNode *argument = arguments[i]; 99 TBasicType argType = argument->getAsTyped()->getType().getBasicType(); 100 if (argType == EbtInt || argType == EbtUInt) 101 { 102 indexes.push_back(i); 103 } 104 } 105 106 std::vector<std::vector<int>> combinations = GetImplicitConversionCombinations(indexes); 107 for (const std::vector<int> &combination : combinations) 108 { 109 // combination: ordered list of indexes for arguments that should be converted to float 110 std::string newName(functionName); 111 newName += kFunctionMangledNameSeparator; 112 // combination[currentIndex] represents index of next argument to be converted 113 int currentIndex = 0; 114 for (int i = 0; i < (int)arguments.size(); i++) 115 { 116 TIntermNode *argument = arguments[i]; 117 118 if (currentIndex != static_cast<int>(combination.size()) && 119 combination[currentIndex] == i) 120 { 121 // Convert 122 TType type = argument->getAsTyped()->getType(); 123 type.setBasicType(EbtFloat); 124 newName += type.getMangledName(); 125 currentIndex++; 126 } 127 else 128 { 129 // Don't convert 130 newName += argument->getAsTyped()->getType().getMangledName(); 131 } 132 } 133 target.push_back(ImmutableString(newName)); 134 } 135 136 return target; 137 } 138 139 std::vector<ImmutableString> TFunctionLookup::getMangledNamesForImplicitConversions() const 140 { 141 return GetMangledNames(mName.data(), mArguments); 142 } 143 144 bool TFunctionLookup::isConstructor() const 145 { 146 return mConstructorType != nullptr; 147 } 148 149 const TType &TFunctionLookup::constructorType() const 150 { 151 return *mConstructorType; 152 } 153 154 void TFunctionLookup::setThisNode(TIntermTyped *thisNode) 155 { 156 mThisNode = thisNode; 157 } 158 159 TIntermTyped *TFunctionLookup::thisNode() const 160 { 161 return mThisNode; 162 } 163 164 void TFunctionLookup::addArgument(TIntermTyped *argument) 165 { 166 mArguments.push_back(argument); 167 } 168 169 TIntermSequence &TFunctionLookup::arguments() 170 { 171 return mArguments; 172 } 173 174 const TSymbol *TFunctionLookup::symbol() const 175 { 176 return mSymbol; 177 } 178 179 } // namespace sh