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[](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 
     62 Symbol* SymbolTable::takeOwnership(Symbol* s) {
     63     fOwnedPointers.push_back(std::unique_ptr<Symbol>(s));
     64     return s;
     65 }
     66 
     67 void 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 
     72 void 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 
    101 void 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