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 [](const String & name)24const Symbol* SymbolTable::operator[](const String& 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 fOwnedPointers.push_back(std::unique_ptr<Symbol>(s)); 64 return s; 65 } 66 add(const String & name,std::unique_ptr<Symbol> symbol)67void SymbolTable::add(const String& name, std::unique_ptr<Symbol> symbol) { 68 this->addWithoutOwnership(name, symbol.get()); 69 fOwnedPointers.push_back(std::move(symbol)); 70 } 71 addWithoutOwnership(const String & name,const Symbol * symbol)72void SymbolTable::addWithoutOwnership(const String& name, const Symbol* symbol) { 73 const auto& existing = fSymbols.find(name); 74 if (existing == fSymbols.end()) { 75 fSymbols[name] = symbol; 76 } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) { 77 const Symbol* oldSymbol = existing->second; 78 if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) { 79 std::vector<const FunctionDeclaration*> functions; 80 functions.push_back((const FunctionDeclaration*) oldSymbol); 81 functions.push_back((const FunctionDeclaration*) symbol); 82 UnresolvedFunction* u = new UnresolvedFunction(std::move(functions)); 83 fSymbols[name] = u; 84 this->takeOwnership(u); 85 } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) { 86 std::vector<const FunctionDeclaration*> functions; 87 for (const auto* f : ((UnresolvedFunction&) *oldSymbol).fFunctions) { 88 functions.push_back(f); 89 } 90 functions.push_back((const FunctionDeclaration*) symbol); 91 UnresolvedFunction* u = new UnresolvedFunction(std::move(functions)); 92 fSymbols[name] = u; 93 this->takeOwnership(u); 94 } 95 } else { 96 fErrorReporter.error(symbol->fPosition, "symbol '" + name + "' was already defined"); 97 } 98 } 99 100 markAllFunctionsBuiltin()101void SymbolTable::markAllFunctionsBuiltin() { 102 for (const auto& pair : fSymbols) { 103 switch (pair.second->fKind) { 104 case Symbol::kFunctionDeclaration_Kind: 105 ((FunctionDeclaration&) *pair.second).fBuiltin = true; 106 break; 107 case Symbol::kUnresolvedFunction_Kind: 108 for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) { 109 ((FunctionDeclaration*) f)->fBuiltin = true; 110 } 111 break; 112 default: 113 break; 114 } 115 } 116 } 117 118 } // namespace 119