diff options
Diffstat (limited to 'symtab.cc')
-rw-r--r-- | symtab.cc | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -27,8 +27,18 @@ #include "log.h" #include "strutil.h" +#include "var.h" + +struct SymbolData { + SymbolData() + : gv(kUndefined) { + } + + Var* gv; +}; vector<string*>* g_symbols; +static vector<SymbolData> g_symbol_data; Symbol kEmptySym = Symbol(Symbol::IsUninitialized()); Symbol kShellSym = Symbol(Symbol::IsUninitialized()); @@ -37,6 +47,45 @@ Symbol::Symbol(int v) : v_(v) { } +Var* Symbol::GetGlobalVar() const { + if (static_cast<size_t>(v_) >= g_symbol_data.size()) { + g_symbol_data.resize(v_ + 1); + } + Var* v = g_symbol_data[v_].gv; + if (v->Origin() == VarOrigin::ENVIRONMENT || + v->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { + Vars::add_used_env_vars(*this); + } + return v; +} + +void Symbol::SetGlobalVar(Var* v) const { + if (static_cast<size_t>(v_) >= g_symbol_data.size()) { + g_symbol_data.resize(v_ + 1); + } + Var* orig = g_symbol_data[v_].gv; + if (orig->Origin() == VarOrigin::OVERRIDE || + orig->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { + return; + } + if (orig->Origin() == VarOrigin::AUTOMATIC) { + ERROR("overriding automatic variable is not implemented yet"); + } + if (orig->IsDefined()) + delete orig; + g_symbol_data[v_].gv = v; +} + +ScopedGlobalVar::ScopedGlobalVar(Symbol name, Var* var) + : name_(name), orig_(NULL) { + orig_ = name.GetGlobalVar(); + g_symbol_data[name_.val()].gv = var; +} + +ScopedGlobalVar::~ScopedGlobalVar() { + g_symbol_data[name_.val()].gv = orig_; +} + class Symtab { public: Symtab() { |