mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
class for referring to definitions of variables or record fields
This commit is contained in:
parent
9b549e4034
commit
d2d681c2a5
3 changed files with 262 additions and 0 deletions
154
src/script_opt/DefItem.cc
Normal file
154
src/script_opt/DefItem.cc
Normal file
|
@ -0,0 +1,154 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "DefItem.h"
|
||||
#include "Expr.h"
|
||||
|
||||
|
||||
namespace zeek::detail {
|
||||
|
||||
|
||||
DefinitionItem::DefinitionItem(const ID* _id)
|
||||
: name(_id->Name())
|
||||
{
|
||||
is_id = true;
|
||||
id = _id;
|
||||
di = nullptr;
|
||||
field_name = nullptr;
|
||||
|
||||
t = id->GetType();
|
||||
|
||||
CheckForRecord();
|
||||
}
|
||||
|
||||
DefinitionItem::DefinitionItem(const DefinitionItem* _di,
|
||||
const char* _field_name, TypePtr _t)
|
||||
{
|
||||
is_id = false;
|
||||
id = nullptr;
|
||||
di = _di;
|
||||
field_name = _field_name;
|
||||
|
||||
t = std::move(_t);
|
||||
|
||||
name += di->Name();
|
||||
name += '$';
|
||||
name += field_name;
|
||||
|
||||
CheckForRecord();
|
||||
}
|
||||
|
||||
std::shared_ptr<DefinitionItem>
|
||||
DefinitionItem::FindField(const char* field) const
|
||||
{
|
||||
if ( ! IsRecord() )
|
||||
return nullptr;
|
||||
|
||||
auto offset = rt->FieldOffset(field);
|
||||
|
||||
return FindField(offset);
|
||||
}
|
||||
|
||||
std::shared_ptr<DefinitionItem> DefinitionItem::FindField(int offset) const
|
||||
{
|
||||
if ( ! IsRecord() )
|
||||
return nullptr;
|
||||
|
||||
return (*fields)[offset];
|
||||
}
|
||||
|
||||
std::shared_ptr<DefinitionItem>
|
||||
DefinitionItem::CreateField(const char* field, TypePtr t)
|
||||
{
|
||||
auto offset = rt->FieldOffset(field);
|
||||
|
||||
if ( (*fields)[offset] )
|
||||
return (*fields)[offset];
|
||||
|
||||
(*fields)[offset] =
|
||||
std::make_shared<DefinitionItem>(this, field, std::move(t));
|
||||
|
||||
return (*fields)[offset];
|
||||
}
|
||||
|
||||
std::shared_ptr<DefinitionItem>
|
||||
DefinitionItem::CreateField(int offset, TypePtr t)
|
||||
{
|
||||
if ( (*fields)[offset] )
|
||||
return (*fields)[offset];
|
||||
|
||||
auto field = rt->FieldName(offset);
|
||||
|
||||
(*fields)[offset] =
|
||||
std::make_shared<DefinitionItem>(this, field, std::move(t));
|
||||
|
||||
return (*fields)[offset];
|
||||
}
|
||||
|
||||
void DefinitionItem::CheckForRecord()
|
||||
{
|
||||
if ( ! IsRecord() )
|
||||
{
|
||||
rt = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
rt = t->AsRecordType();
|
||||
num_fields = rt->NumFields();
|
||||
fields = std::vector<std::shared_ptr<DefinitionItem>>(num_fields);
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<DefinitionItem> DefItemMap::GetExprDI(const Expr* expr)
|
||||
{
|
||||
if ( expr->Tag() == EXPR_NAME )
|
||||
{
|
||||
auto id_e = expr->AsNameExpr();
|
||||
auto id = id_e->Id();
|
||||
return GetID_DI(id);
|
||||
}
|
||||
|
||||
else if ( expr->Tag() == EXPR_FIELD )
|
||||
{
|
||||
auto f = expr->AsFieldExpr();
|
||||
auto r = f->Op();
|
||||
|
||||
auto r_def = GetExprDI(r);
|
||||
|
||||
if ( ! r_def )
|
||||
return nullptr;
|
||||
|
||||
auto field = f->FieldName();
|
||||
return r_def->FindField(field);
|
||||
}
|
||||
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<DefinitionItem> DefItemMap::GetID_DI(const ID* id)
|
||||
{
|
||||
auto di = i2d.find(id);
|
||||
if ( di == i2d.end() )
|
||||
{
|
||||
auto new_entry = std::make_shared<DefinitionItem>(id);
|
||||
i2d[id] = new_entry;
|
||||
return new_entry;
|
||||
}
|
||||
else
|
||||
return di->second;
|
||||
}
|
||||
|
||||
const DefinitionItem* DefItemMap::GetConstID_DI(const ID* id) const
|
||||
{
|
||||
auto di = i2d.find(id);
|
||||
return di == i2d.end() ? nullptr : di->second.get();
|
||||
}
|
||||
|
||||
const DefinitionItem* DefItemMap::GetConstID_DI(const DefinitionItem* di,
|
||||
const char* field_name) const
|
||||
{
|
||||
return di->FindField(field_name).get();
|
||||
}
|
||||
|
||||
|
||||
} // zeek::detail
|
Loading…
Add table
Add a link
Reference in a new issue