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 "SkSLSymbolTable.h" 9 #include "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 ASSERT(functions.size() > 1); 54 return this->takeOwnership(new UnresolvedFunction(functions)); 55 } 56 } 57 } 58 } 59 return entry->second; 60 } 61 takeOwnership(Symbol * s)62Symbol* SymbolTable::takeOwnership(Symbol* s) { 63 fOwnedSymbols.emplace_back(s); 64 return s; 65 } 66 takeOwnership(IRNode * n)67IRNode* SymbolTable::takeOwnership(IRNode* n) { 68 fOwnedNodes.emplace_back(n); 69 return n; 70 } 71 add(StringFragment name,std::unique_ptr<Symbol> symbol)72void SymbolTable::add(StringFragment name, std::unique_ptr<Symbol> symbol) { 73 this->addWithoutOwnership(name, symbol.get()); 74 this->takeOwnership(symbol.release()); 75 } 76 addWithoutOwnership(StringFragment name,const Symbol * symbol)77void SymbolTable::addWithoutOwnership(StringFragment name, const Symbol* symbol) { 78 const auto& existing = fSymbols.find(name); 79 if (existing == fSymbols.end()) { 80 fSymbols[name] = symbol; 81 } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) { 82 const Symbol* oldSymbol = existing->second; 83 if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) { 84 std::vector<const FunctionDeclaration*> functions; 85 functions.push_back((const FunctionDeclaration*) oldSymbol); 86 functions.push_back((const FunctionDeclaration*) symbol); 87 UnresolvedFunction* u = new UnresolvedFunction(std::move(functions)); 88 fSymbols[name] = u; 89 this->takeOwnership(u); 90 } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) { 91 std::vector<const FunctionDeclaration*> functions; 92 for (const auto* f : ((UnresolvedFunction&) *oldSymbol).fFunctions) { 93 functions.push_back(f); 94 } 95 functions.push_back((const FunctionDeclaration*) symbol); 96 UnresolvedFunction* u = new UnresolvedFunction(std::move(functions)); 97 fSymbols[name] = u; 98 this->takeOwnership(u); 99 } 100 } else { 101 fErrorReporter.error(symbol->fOffset, "symbol '" + name + "' was already defined"); 102 } 103 } 104 105 markAllFunctionsBuiltin()106void SymbolTable::markAllFunctionsBuiltin() { 107 for (const auto& pair : fSymbols) { 108 switch (pair.second->fKind) { 109 case Symbol::kFunctionDeclaration_Kind: 110 ((FunctionDeclaration&) *pair.second).fBuiltin = true; 111 break; 112 case Symbol::kUnresolvedFunction_Kind: 113 for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) { 114 ((FunctionDeclaration*) f)->fBuiltin = true; 115 } 116 break; 117 default: 118 break; 119 } 120 } 121 } 122 begin()123std::map<StringFragment, const Symbol*>::iterator SymbolTable::begin() { 124 return fSymbols.begin(); 125 } 126 end()127std::map<StringFragment, const Symbol*>::iterator SymbolTable::end() { 128 return fSymbols.end(); 129 } 130 131 132 } // namespace 133