1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "src/sksl/ir/SkSLSymbolTable.h" 9 #include "src/sksl/ir/SkSLUnresolvedFunction.h" 10 11 namespace SkSL { 12 GetFunctions(const Symbol & s)13std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol& s) { 14 switch (s.fKind) { 15 case Symbol::kFunctionDeclaration_Kind: 16 return { &((FunctionDeclaration&) s) }; 17 case Symbol::kUnresolvedFunction_Kind: 18 return ((UnresolvedFunction&) s).fFunctions; 19 default: 20 return std::vector<const FunctionDeclaration*>(); 21 } 22 } 23 operator [](StringFragment name)24const Symbol* SymbolTable::operator[](StringFragment name) { 25 const auto& entry = fSymbols.find(name); 26 if (entry == fSymbols.end()) { 27 if (fParent) { 28 return (*fParent)[name]; 29 } 30 return nullptr; 31 } 32 if (fParent) { 33 auto functions = GetFunctions(*entry->second); 34 if (functions.size() > 0) { 35 bool modified = false; 36 const Symbol* previous = (*fParent)[name]; 37 if (previous) { 38 auto previousFunctions = GetFunctions(*previous); 39 for (const FunctionDeclaration* prev : previousFunctions) { 40 bool found = false; 41 for (const FunctionDeclaration* current : functions) { 42 if (current->matches(*prev)) { 43 found = true; 44 break; 45 } 46 } 47 if (!found) { 48 functions.push_back(prev); 49 modified = true; 50 } 51 } 52 if (modified) { 53 SkASSERT(functions.size() > 1); 54 return this->takeOwnership(std::unique_ptr<Symbol>( 55 new UnresolvedFunction(functions))); 56 } 57 } 58 } 59 } 60 return entry->second; 61 } 62 takeOwnership(std::unique_ptr<Symbol> s)63Symbol* SymbolTable::takeOwnership(std::unique_ptr<Symbol> s) { 64 Symbol* result = s.get(); 65 fOwnedSymbols.push_back(std::move(s)); 66 return result; 67 } 68 takeOwnership(std::unique_ptr<IRNode> n)69IRNode* SymbolTable::takeOwnership(std::unique_ptr<IRNode> n) { 70 IRNode* result = n.get(); 71 fOwnedNodes.push_back(std::move(n)); 72 return result; 73 } 74 add(StringFragment name,std::unique_ptr<Symbol> symbol)75void SymbolTable::add(StringFragment name, std::unique_ptr<Symbol> symbol) { 76 this->addWithoutOwnership(name, symbol.get()); 77 this->takeOwnership(std::move(symbol)); 78 } 79 addWithoutOwnership(StringFragment name,const Symbol * symbol)80void SymbolTable::addWithoutOwnership(StringFragment name, const Symbol* symbol) { 81 const auto& existing = fSymbols.find(name); 82 if (existing == fSymbols.end()) { 83 fSymbols[name] = symbol; 84 } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) { 85 const Symbol* oldSymbol = existing->second; 86 if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) { 87 std::vector<const FunctionDeclaration*> functions; 88 functions.push_back((const FunctionDeclaration*) oldSymbol); 89 functions.push_back((const FunctionDeclaration*) symbol); 90 std::unique_ptr<Symbol> u = std::unique_ptr<Symbol>(new UnresolvedFunction(std::move( 91 functions))); 92 fSymbols[name] = this->takeOwnership(std::move(u)); 93 } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) { 94 std::vector<const FunctionDeclaration*> functions; 95 for (const auto* f : ((UnresolvedFunction&) *oldSymbol).fFunctions) { 96 functions.push_back(f); 97 } 98 functions.push_back((const FunctionDeclaration*) symbol); 99 std::unique_ptr<Symbol> u = std::unique_ptr<Symbol>(new UnresolvedFunction(std::move( 100 functions))); 101 fSymbols[name] = this->takeOwnership(std::move(u)); 102 } 103 } else { 104 fErrorReporter.error(symbol->fOffset, "symbol '" + name + "' was already defined"); 105 } 106 } 107 108 markAllFunctionsBuiltin()109void SymbolTable::markAllFunctionsBuiltin() { 110 for (const auto& pair : fSymbols) { 111 switch (pair.second->fKind) { 112 case Symbol::kFunctionDeclaration_Kind: 113 if (!((FunctionDeclaration&)*pair.second).fDefined) { 114 ((FunctionDeclaration&)*pair.second).fBuiltin = true; 115 } 116 break; 117 case Symbol::kUnresolvedFunction_Kind: 118 for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) { 119 if (!((FunctionDeclaration*)f)->fDefined) { 120 ((FunctionDeclaration*)f)->fBuiltin = true; 121 } 122 } 123 break; 124 default: 125 break; 126 } 127 } 128 } 129 begin()130std::unordered_map<StringFragment, const Symbol*>::iterator SymbolTable::begin() { 131 return fSymbols.begin(); 132 } 133 end()134std::unordered_map<StringFragment, const Symbol*>::iterator SymbolTable::end() { 135 return fSymbols.end(); 136 } 137 138 139 } // namespace 140