zeek/src/Scope.h
Jon Siwek cf196bb148 Merge branch 'leaks' of https://github.com/MaxKellermann/zeek
Only one instance of base_type() getting a NewRef instead of AdoptRef
fixed in merge.  All other changes are superficial formatting and
factoring.

* 'leaks' of https://github.com/MaxKellermann/zeek: (22 commits)
  Stmt: use class IntrusivePtr
  Stmt: remove unused default constructors and `friend` declarations
  Val: remove unimplemented prototype recover_val()
  Val: cast_value_to_type() returns IntrusivePtr
  Val: use IntrusivePtr in check_and_promote()
  Val: use nullptr instead of 0
  zeekygen: use class IntrusivePtr
  ID: use class IntrusivePtr
  Expr: use class IntrusivePtr
  Var: copy Location to stack, to fix use-after-free crash bug
  Scope: lookup_ID() and install_ID() return IntrusivePtr<ID>
  Scope: delete duplicate locals
  EventRegistry: automatically delete EventHandlers
  main: destroy event_registry after iosource_mgr
  zeekygen/IdentifierInfo: delete duplicate fields
  main: free the global scope in terminate_bro()
  Scope: pop_scope() returns IntrusivePtr<>
  Scope: unref all inits in destructor
  Var: pass IntrusivePtr to add_global(), add_local() etc.
  plugin/ComponentManager: hold a reference to the EnumType
  ...
2020-02-28 00:48:20 -08:00

110 lines
2.5 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#pragma once
#include <utility>
#include <string>
#include <map>
#include "Obj.h"
#include "BroList.h"
#include "TraverseTypes.h"
template <class T> class IntrusivePtr;
class ID;
class BroType;
class ListVal;
class Scope : public BroObj {
public:
explicit Scope(ID* id, attr_list* al);
~Scope() override;
template<typename N>
ID* Lookup(N&& name) const
{
const auto& entry = local.find(std::forward<N>(name));
if ( entry != local.end() )
return entry->second;
return nullptr;
}
template<typename N>
void Insert(N&& name, ID* id)
{
auto [it, inserted] = local.emplace(std::forward<N>(name), id);
if ( ! inserted )
{
Unref(it->second);
it->second = id;
}
}
template<typename N>
ID* Remove(N&& name)
{
const auto& entry = local.find(std::forward<N>(name));
if ( entry != local.end() )
{
ID* id = entry->second;
local.erase(entry);
return id;
}
return nullptr;
}
ID* ScopeID() const { return scope_id; }
attr_list* Attrs() const { return attrs; }
BroType* ReturnType() const { return return_type; }
size_t Length() const { return local.size(); }
const std::map<std::string, ID*>& Vars() { return local; }
ID* GenerateTemporary(const char* name);
// Returns the list of variables needing initialization, and
// removes it from this Scope.
id_list* GetInits();
// Adds a variable to the list.
void AddInit(ID* id) { inits->push_back(id); }
void Describe(ODesc* d) const override;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
ID* scope_id;
attr_list* attrs;
BroType* return_type;
std::map<std::string, ID*> local;
id_list* inits;
};
extern bool in_debug;
// If no_global is true, don't search in the default "global" namespace.
extern IntrusivePtr<ID> lookup_ID(const char* name, const char* module,
bool no_global = false,
bool same_module_only = false,
bool check_export = true);
extern IntrusivePtr<ID> install_ID(const char* name, const char* module_name,
bool is_global, bool is_export);
extern void push_scope(ID* id, attr_list* attrs);
extern void push_existing_scope(Scope* scope);
// Returns the one popped off.
extern IntrusivePtr<Scope> pop_scope();
extern Scope* current_scope();
extern Scope* global_scope();
// Current module (identified by its name).
extern std::string current_module;