Chromium Code Reviews| Index: src/sksl/ir/SkSLSymbolTable.cpp |
| diff --git a/src/sksl/ir/SkSLSymbolTable.cpp b/src/sksl/ir/SkSLSymbolTable.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..577ff460d8a06d0b41ab060890931a5d5e4ac803 |
| --- /dev/null |
| +++ b/src/sksl/ir/SkSLSymbolTable.cpp |
| @@ -0,0 +1,85 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| + #include "SkSLSymbolTable.h" |
| + |
| +namespace SkSL { |
| + |
| +std::vector<std::shared_ptr<FunctionDeclaration>> SymbolTable::GetFunctions( |
| + const std::shared_ptr<Symbol>& s) { |
| + switch (s->fKind) { |
| + case Symbol::kFunctionDeclaration_Kind: |
| + return { std::static_pointer_cast<FunctionDeclaration>(s) }; |
| + case Symbol::kUnresolvedFunction_Kind: |
| + return std::static_pointer_cast<UnresolvedFunction>(s)->fFunctions; |
|
dogben
2016/06/28 02:14:55
nit: ((UnresolvedFunction*)s.get())->fFunctions av
|
| + default: |
| + return { }; |
| + } |
| +} |
| + |
| +std::shared_ptr<Symbol> SymbolTable::operator[](const std::string& name) { |
| + auto entry = fSymbols.find(name); |
|
dogben
2016/06/28 02:14:55
nit: const ref
|
| + if (entry == fSymbols.end()) { |
| + if (fParent) { |
| + return (*fParent)[name]; |
| + } |
| + return nullptr; |
| + } |
| + if (fParent) { |
| + auto functions = GetFunctions(entry->second); |
| + if (functions.size() > 0) { |
| + bool modified = false; |
| + std::shared_ptr<Symbol> previous = (*fParent)[name]; |
| + if (previous) { |
| + auto previousFunctions = GetFunctions(previous); |
| + for (std::shared_ptr<FunctionDeclaration> prev : previousFunctions) { |
|
dogben
2016/06/28 02:14:55
nit: const ref
|
| + bool found = false; |
| + for (std::shared_ptr<FunctionDeclaration> current : functions) { |
|
dogben
2016/06/28 02:14:55
nit: const ref
|
| + if (current->matches(*prev)) { |
| + found = true; |
| + break; |
| + } |
| + } |
| + if (!found) { |
| + functions.push_back(prev); |
| + modified = true; |
| + } |
| + } |
| + if (modified) { |
| + ASSERT(functions.size() > 1); |
| + return std::shared_ptr<Symbol>(new UnresolvedFunction(functions)); |
| + } |
| + } |
| + } |
| + } |
| + return entry->second; |
| +} |
| + |
| +void SymbolTable::add(const std::string& name, std::shared_ptr<Symbol> symbol) { |
| + auto existing = fSymbols.find(name); |
|
dogben
2016/06/28 02:14:55
nit: const ref
|
| + if (existing == fSymbols.end()) { |
| + fSymbols[name] = symbol; |
| + } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) { |
| + std::shared_ptr<Symbol> oldSymbol = existing->second; |
|
dogben
2016/06/28 02:14:55
nit: const ref
|
| + if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) { |
| + std::vector<std::shared_ptr<FunctionDeclaration>> functions; |
| + functions.push_back(std::static_pointer_cast<FunctionDeclaration>(oldSymbol)); |
| + functions.push_back(std::static_pointer_cast<FunctionDeclaration>(symbol)); |
| + fSymbols[name] = std::shared_ptr<Symbol>(new UnresolvedFunction(functions)); |
|
dogben
2016/06/28 02:14:55
nit: fSymbols[name].reset(new UnresolvedFunction(s
|
| + } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) { |
| + std::vector<std::shared_ptr<FunctionDeclaration>> functions; |
| + for (auto f : std::static_pointer_cast<UnresolvedFunction>(oldSymbol)->fFunctions) { |
|
dogben
2016/06/28 02:14:55
nit: const ref
|
| + functions.push_back(f); |
| + } |
| + functions.push_back(std::static_pointer_cast<FunctionDeclaration>(symbol)); |
| + fSymbols[name] = std::shared_ptr<Symbol>(new UnresolvedFunction(functions)); |
| + } |
| + } else { |
| + fErrorReporter.error(symbol->fPosition, "symbol '" + name + "' was already defined"); |
| + } |
| + } |
| +} // namespace |