// Copyright (C) 2020 Free Software Foundation, Inc.
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3. If not see
// .
#pragma once
#include "rust-system.h"
#include "rust-backend.h"
#include "scope.h"
namespace Rust {
namespace Compile {
class Scope
{
public:
Scope (Backend *backend) : backend (backend) {}
~Scope () {}
void Push ()
{
fndecls.Push ();
vars.Push ();
types.Push ();
structDecls.Push ();
}
void Pop ()
{
fndecls.Pop ();
vars.Pop ();
types.Pop ();
structDecls.Pop ();
}
void PushCurrentFunction (std::string name, Bfunction *fn, Btype *retType,
Bvariable *retDecl)
{
fns.push_back (fn);
fnRetType.push_back (retType);
fnRetDecl.push_back (retDecl);
}
Bfunction *PopCurrentFunction ()
{
auto ret = fns.back ();
fns.pop_back ();
fnRetType.pop_back ();
fnRetDecl.pop_back ();
return ret;
}
Bfunction *GetCurrentFndecl () { return fns.back (); }
Btype *GetCurrentFnRetType () { return fnRetType.back (); }
Bvariable *GetCurrentFnRetDecl () { return fnRetDecl.back (); }
Btype *GetFnRetType (Bfunction *fn)
{
auto it = fnRetTypeMapping.find (fn);
if (it == fnRetTypeMapping.end ())
{
return NULL;
}
return it->second;
}
void PushBlock (Bblock *block)
{
blocks.push_back (block);
std::vector empty;
context.push_back (empty);
}
Bblock *PopBlock ()
{
auto ret = blocks.back ();
blocks.pop_back ();
auto stmts = context.back ();
context.pop_back ();
backend->block_add_statements (ret, stmts);
return ret;
}
Bblock *CurBlock () { return blocks.back (); }
void AddStatement (Bstatement *stmt) { context.back ().push_back (stmt); }
void InsertStructDecl (std::string name, AST::StructStruct *decl)
{
structDecls.Insert (name, decl);
}
bool LookupStructDecl (std::string name, AST::StructStruct **decl)
{
return structDecls.Lookup (name, decl);
}
void InsertFunction (std::string name, Bfunction *fn, Btype *retType)
{
fndecls.Insert (name, fn);
fnRetTypeMapping[fn] = retType;
}
bool LookupFunction (std::string name, Bfunction **fn)
{
return fndecls.Lookup (name, fn);
}
void InsertType (std::string name, Btype *type) { types.Insert (name, type); }
bool LookupType (std::string name, Btype **type)
{
return types.Lookup (name, type);
}
void InsertVar (std::string name, Bvariable *var) { vars.Insert (name, var); }
bool LookupVar (std::string name, Bvariable **var)
{
return vars.Lookup (name, var);
}
private:
Backend *backend;
::std::vector fns;
::std::vector blocks;
::std::vector< ::std::vector > context;
::std::vector< ::Btype *> fnRetType;
::std::vector< ::Bvariable *> fnRetDecl;
::std::map fnRetTypeMapping;
Analysis::Scope fndecls;
Analysis::Scope vars;
Analysis::Scope types;
Analysis::Scope structDecls;
};
} // namespace Compile
} // namespace Rust