Home | History | Annotate | Download | only in ir
      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 
     13 std::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 
     24 const 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 
     62 Symbol* SymbolTable::takeOwnership(Symbol* s) {
     63     fOwnedSymbols.emplace_back(s);
     64     return s;
     65 }
     66 
     67 IRNode* SymbolTable::takeOwnership(IRNode* n) {
     68     fOwnedNodes.emplace_back(n);
     69     return n;
     70 }
     71 
     72 void SymbolTable::add(StringFragment name, std::unique_ptr<Symbol> symbol) {
     73     this->addWithoutOwnership(name, symbol.get());
     74     this->takeOwnership(symbol.release());
     75 }
     76 
     77 void 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 
    106 void 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 
    123 std::map<StringFragment, const Symbol*>::iterator SymbolTable::begin() {
    124     return fSymbols.begin();
    125 }
    126 
    127 std::map<StringFragment, const Symbol*>::iterator SymbolTable::end() {
    128     return fSymbols.end();
    129 }
    130 
    131 
    132 } // namespace
    133