shift much of the internal use of ID* identifier pointers over to IDPtr objects

This commit is contained in:
Vern Paxson 2025-08-31 08:58:19 -07:00
parent 1c7c1b62f6
commit 693aa244f9
43 changed files with 301 additions and 345 deletions

View file

@ -4226,7 +4226,7 @@ LambdaExpr::LambdaExpr(FunctionIngredientsPtr arg_ing, IDPList arg_outer_ids, st
if ( captures ) {
outer_ids.clear();
for ( auto& c : *captures )
outer_ids.append(c.Id().get());
outer_ids.emplace_back(c.Id());
}
// Install a primary version of the function globally. This is used
@ -4271,7 +4271,7 @@ LambdaExpr::LambdaExpr(LambdaExpr* orig) : Expr(EXPR_LAMBDA) {
// We need to have our own copies of the outer IDs and captures so
// we can rename them when inlined.
for ( auto i : orig->outer_ids )
outer_ids.append(i);
outer_ids.emplace_back(i);
if ( orig->captures ) {
captures = std::vector<FuncType::Capture>{};
@ -4295,11 +4295,11 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
return true;
}
std::set<const ID*> outer_is_matched;
std::set<const ID*> capture_is_matched;
std::unordered_set<IDPtr> outer_is_matched;
std::unordered_set<IDPtr> capture_is_matched;
for ( const auto& c : *captures ) {
auto cid = c.Id().get();
auto cid = c.Id();
if ( ! cid )
// This happens for undefined/inappropriate
@ -4317,7 +4317,7 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
return false;
}
for ( auto id : outer_ids )
for ( const auto& id : outer_ids )
if ( cid == id ) {
outer_is_matched.insert(id);
capture_is_matched.insert(cid);
@ -4337,7 +4337,7 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
}
for ( const auto& c : *captures ) {
auto cid = c.Id().get();
const auto& cid = c.Id();
if ( cid && ! capture_is_matched.contains(cid) ) {
auto msg = util::fmt("%s is captured but not used inside %s", cid->Name(), desc);
if ( when_parent )

View file

@ -49,7 +49,8 @@ enum IDScope : uint8_t { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL };
class ID;
using IDPtr = IntrusivePtr<ID>;
using IDSet = std::unordered_set<const ID*>;
using IDPList = std::vector<IDPtr>;
using IDSet = std::unordered_set<IDPtr>;
class IDOptInfo;

View file

@ -536,14 +536,7 @@ Case::Case(ListExprPtr arg_expr_cases, IDPList* arg_type_cases, StmtPtr arg_s)
}
}
Case::~Case() {
if ( type_cases ) {
for ( const auto& id : *type_cases )
Unref(id);
delete type_cases;
}
}
Case::~Case() { delete type_cases; }
void Case::Describe(ODesc* d) const {
if ( ! (expr_cases || type_cases) ) {
@ -580,9 +573,10 @@ void Case::Describe(ODesc* d) const {
if ( type_cases ) {
const IDPList& t = *type_cases;
d->AddCount(t.length());
auto n = t.size();
d->AddCount(n);
loop_over_list(t, i) {
for ( auto i = 0U; i < n; ++i ) {
if ( i > 0 && d->IsReadable() )
d->Add(",");
@ -763,21 +757,21 @@ bool SwitchStmt::AddCaseLabelValueMapping(const Val* v, int idx) {
return true;
}
bool SwitchStmt::AddCaseLabelTypeMapping(ID* t, int idx) {
bool SwitchStmt::AddCaseLabelTypeMapping(IDPtr t, int idx) {
for ( const auto& i : case_label_type_list ) {
if ( same_type(i.first->GetType(), t->GetType()) )
return false;
}
auto e = std::make_pair(t, idx);
auto e = std::make_pair(std::move(t), idx);
case_label_type_list.push_back(e);
return true;
}
std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const {
std::pair<int, IDPtr> SwitchStmt::FindCaseLabelMatch(const Val* v) const {
int label_idx = -1;
ID* label_id = nullptr;
IDPtr label_id;
// Find matching expression cases.
if ( case_label_hash_map.Length() ) {
@ -817,7 +811,7 @@ ValPtr SwitchStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) {
auto m = FindCaseLabelMatch(v);
int matching_label_idx = m.first;
ID* matching_id = m.second;
auto matching_id = m.second;
if ( matching_label_idx == -1 )
return nullptr;
@ -1015,7 +1009,7 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr) : ExprStmt(STMT_FOR,
if ( e->GetType()->Tag() == TYPE_TABLE ) {
const auto& indices = e->GetType()->AsTableType()->GetIndexTypes();
if ( loop_vars->length() == 1 && (*loop_vars)[0]->IsBlank() ) {
if ( loop_vars->size() == 1 && (*loop_vars)[0]->IsBlank() ) {
// Special case support for looping with a single loop_var
// ignoring the full index of a table.
//
@ -1024,12 +1018,12 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr) : ExprStmt(STMT_FOR,
//
return;
}
else if ( static_cast<int>(indices.size()) != loop_vars->length() ) {
else if ( static_cast<int>(indices.size()) != loop_vars->size() ) {
e->Error("wrong index size");
return;
}
for ( auto i = 0u; i < indices.size(); i++ ) {
for ( size_t i = 0; i < indices.size(); i++ ) {
const auto& ind_type = indices[i];
const auto& lv = (*loop_vars)[i];
const auto& lvt = lv->GetType();
@ -1042,14 +1036,13 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr) : ExprStmt(STMT_FOR,
e->Error("type clash in iteration", lvt.get());
}
else {
add_local({NewRef{}, lv}, ind_type, INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
}
else
add_local(lv, ind_type, INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
}
}
else if ( e->GetType()->Tag() == TYPE_VECTOR ) {
if ( loop_vars->length() != 1 ) {
if ( loop_vars->size() != 1 ) {
e->Error("iterating over a vector requires only a single index type");
return;
}
@ -1061,7 +1054,7 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr) : ExprStmt(STMT_FOR,
// nop
}
else if ( ! t )
add_local({NewRef{}, lv}, base_type(TYPE_COUNT), INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
add_local(lv, base_type(TYPE_COUNT), INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
else if ( ! IsIntegral(t->Tag()) ) {
e->Error("vector index in \"for\" loop must be integral");
@ -1070,7 +1063,7 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr) : ExprStmt(STMT_FOR,
}
else if ( e->GetType()->Tag() == TYPE_STRING ) {
if ( loop_vars->length() != 1 ) {
if ( loop_vars->size() != 1 ) {
e->Error("iterating over a string requires only a single index type");
return;
}
@ -1082,7 +1075,7 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr) : ExprStmt(STMT_FOR,
// nop
}
else if ( ! t )
add_local({NewRef{}, (*loop_vars)[0]}, base_type(TYPE_STRING), INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
add_local((*loop_vars)[0], base_type(TYPE_STRING), INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
else if ( t->Tag() != TYPE_STRING ) {
e->Error("string index in \"for\" loop must be string");
@ -1123,11 +1116,7 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr, IDPtr val_var)
add_local(value_var, yield_type, INIT_SKIP, nullptr, nullptr, VAR_REGULAR);
}
ForStmt::~ForStmt() {
for ( const auto& var : *loop_vars )
Unref(var);
delete loop_vars;
}
ForStmt::~ForStmt() { delete loop_vars; }
ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) {
ValPtr ret;
@ -1142,7 +1131,7 @@ ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) {
// If there are only blank loop_vars (iterating over just the values),
// we can avoid the RecreateIndex() overhead.
bool all_loop_vars_blank = true;
for ( const auto* lv : *loop_vars )
for ( const auto& lv : *loop_vars )
all_loop_vars_blank &= lv->IsBlank();
for ( const auto& lve : *loop_vals ) {
@ -1155,7 +1144,7 @@ ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) {
if ( ! all_loop_vars_blank ) {
auto ind_lv = tv->RecreateIndex(*k);
for ( int i = 0; i < ind_lv->Length(); i++ ) {
const auto* lv = (*loop_vars)[i];
const auto& lv = (*loop_vars)[i];
if ( ! lv->IsBlank() )
f->SetElement(lv, ind_lv->Idx(i));
}
@ -1173,7 +1162,7 @@ ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) {
VectorVal* vv = v->AsVectorVal();
const auto& raw_vv = vv->RawVec();
for ( auto i = 0u; i < vv->Size(); ++i ) {
for ( size_t i = 0; i < vv->Size(); ++i ) {
if ( ! raw_vv[i] )
continue;
@ -1182,7 +1171,7 @@ ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) {
if ( value_var )
f->SetElement(value_var, vv->ValAt(i));
const auto* lv = (*loop_vars)[0];
const auto& lv = (*loop_vars)[0];
if ( ! lv->IsBlank() )
f->SetElement(lv, val_mgr->Count(i));
@ -1227,16 +1216,16 @@ void ForStmt::StmtDescribe(ODesc* d) const {
if ( d->IsReadable() )
d->Add("(");
if ( loop_vars->length() )
if ( ! loop_vars->empty() )
d->Add("[");
loop_over_list(*loop_vars, i) {
for ( size_t i = 0; i < loop_vars->size(); ++i ) {
(*loop_vars)[i]->Describe(d);
if ( i > 0 )
d->Add(",");
}
if ( loop_vars->length() )
if ( ! loop_vars->empty() )
d->Add("]");
if ( value_var ) {
@ -1775,22 +1764,16 @@ void WhenInfo::BuildProfile() {
break;
}
if ( ! is_present ) {
IDPtr wl_ptr = {NewRef{}, const_cast<ID*>(wl)};
cl->emplace_back(std::move(wl_ptr), false);
}
if ( ! is_present )
cl->emplace_back(wl, false);
// In addition, don't treat them as external locals that
// existed at the onset.
when_expr_locals_set.erase(wl);
}
for ( auto& w : when_expr_locals_set ) {
// We need IDPtr versions of the locals so we can manipulate
// them during script optimization.
auto non_const_w = const_cast<ID*>(w);
when_expr_locals.emplace_back(NewRef{}, non_const_w);
}
for ( auto& w : when_expr_locals_set )
when_expr_locals.emplace_back(w);
}
void WhenInfo::Build(StmtPtr ws) {

View file

@ -194,7 +194,7 @@ protected:
int DefaultCaseIndex() const { return default_case_idx; }
const auto& ValueMap() const { return case_label_value_map; }
const std::vector<std::pair<ID*, int>>* TypeMap() const { return &case_label_type_list; }
const std::vector<std::pair<IDPtr, int>>* TypeMap() const { return &case_label_type_list; }
const CompositeHash* CompHash() const { return comp_hash; }
ValPtr DoExec(Frame* f, Val* v, StmtFlowType& flow) override;
@ -212,20 +212,20 @@ protected:
// Adds an entry in case_label_type_map for the given type (w/ ID) to
// associate it with the given index in the cases list. If an entry
// for the type already exists, returns false; else returns true.
bool AddCaseLabelTypeMapping(ID* t, int idx);
bool AddCaseLabelTypeMapping(IDPtr t, int idx);
// Returns index of a case label that matches the value, or
// default_case_idx if no case label matches (which may be -1 if
// there's no default label). The second tuple element is the ID of
// the matching type-based case if it defines one.
std::pair<int, ID*> FindCaseLabelMatch(const Val* v) const;
std::pair<int, IDPtr> FindCaseLabelMatch(const Val* v) const;
case_list* cases = nullptr;
int default_case_idx = -1;
CompositeHash* comp_hash = nullptr;
std::unordered_map<const Val*, int> case_label_value_map;
PDict<int> case_label_hash_map;
std::vector<std::pair<ID*, int>> case_label_type_list;
std::vector<std::pair<IDPtr, int>> case_label_type_list;
};
class EventStmt final : public ExprStmt {

View file

@ -44,7 +44,7 @@ TraversalCode trigger::TriggerTraversalCallback::PreExpr(const Expr* expr) {
switch ( expr->Tag() ) {
case EXPR_NAME: {
const auto* e = static_cast<const NameExpr*>(expr);
auto id = e->Id();
auto id = e->IdPtr();
if ( id->IsGlobal() )
globals.insert(id);
@ -184,7 +184,7 @@ void Trigger::ReInit(std::vector<ValPtr> index_expr_results) {
}
for ( auto g : globals ) {
Register(g);
Register(g.get());
auto& v = g->GetVal();
if ( v && v->Modifiable() )

View file

@ -667,7 +667,7 @@ public:
TraversalCode PostExpr(const Expr*) override;
std::vector<ScopePtr> scopes;
std::unordered_set<ID*> outer_id_references;
std::unordered_set<IDPtr> outer_id_references;
};
TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr) {
@ -681,7 +681,7 @@ TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr) {
return TC_CONTINUE;
auto e = static_cast<const NameExpr*>(expr);
auto id = e->Id();
auto id = e->IdPtr();
if ( id->IsGlobal() )
return TC_CONTINUE;
@ -760,8 +760,8 @@ IDPList gather_outer_ids(ScopePtr scope, StmtPtr body) {
IDPList idl;
for ( auto id : cb.outer_id_references )
idl.append(id);
for ( auto& id : cb.outer_id_references )
idl.emplace_back(std::move(id));
return idl;
}

View file

@ -20,7 +20,6 @@ class Type;
using ValPList = PList<Val>;
using ExprPList = PList<detail::Expr>;
using IDPList = PList<detail::ID>;
using TypePList = PList<Type>;
using AttrPList = PList<detail::Attr>;
using TimerPList = PList<detail::Timer, ListOrder::UNORDERED>;

View file

@ -331,7 +331,7 @@ static void refine_location(zeek::detail::ID* id) {
bool b;
char* str;
zeek::detail::ID* id;
zeek::IDPList* id_l;
zeek::detail::IDPList* id_l;
zeek::detail::InitClass ic;
zeek::Val* val;
zeek::RE_Matcher* re;
@ -1996,12 +1996,12 @@ case:
case_type_list:
case_type_list ',' case_type
{ $1->push_back($3); }
{ $1->push_back({AdoptRef{}, $3}); }
|
case_type
{
$$ = new IDPList;
$$->push_back($1);
$$->push_back({AdoptRef{}, $1});
}
;
@ -2045,7 +2045,7 @@ for_head:
}
auto* loop_vars = new IDPList;
loop_vars->push_back(loop_var.release());
loop_vars->push_back(loop_var);
$$ = new ForStmt(loop_vars, {AdoptRef{}, $5});
}
@ -2077,7 +2077,7 @@ for_head:
val_var = install_ID($5, module, false, false);
auto* loop_vars = new IDPList;
loop_vars->push_back(key_var.release());
loop_vars->push_back(key_var);
$$ = new ForStmt(loop_vars, {AdoptRef{}, $7}, std::move(val_var));
}
@ -2101,11 +2101,11 @@ for_head:
local_id_list:
local_id_list ',' local_id
{ $1->push_back($3); }
{ $1->push_back({AdoptRef{}, $3}); }
| local_id
{
$$ = new IDPList;
$$->push_back($1);
$$->push_back({AdoptRef{}, $1});
}
;

View file

@ -154,7 +154,7 @@ void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf, c
// An additional constructor just used to generate place-holder
// instances, due to the misdesign that lambdas are identified
// by their Func objects rather than their FuncVal objects.
if ( lambda_ids && lambda_ids->length() > 0 )
if ( lambda_ids && ! lambda_ids->empty() )
Emit("%s_cl(const char* name) : CPPStmt(name, %s) { }", fname, loc_info);
Emit("ValPtr Exec(Frame* f, StmtFlowType& flow) override");
@ -216,7 +216,7 @@ void CPPCompile::BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf, const
// Generate initialization to create and register the lambda.
auto h = pf->HashVal();
auto nl = lambda_ids->length();
auto nl = lambda_ids->size();
bool has_captures = nl > 0;
auto gi = make_shared<LambdaRegistrationInfo>(this, l->Name(), ft, fname + "_cl", h, has_captures);
@ -364,7 +364,7 @@ void CPPCompile::GatherParamNames(vector<string>& p_names, const FuncTypePtr& ft
p_names.emplace_back(lambda_names[id]);
}
const ID* CPPCompile::FindParam(int i, const ProfileFunc* pf) {
IDPtr CPPCompile::FindParam(int i, const ProfileFunc* pf) {
const auto& params = pf->Params();
for ( const auto& p : params )

View file

@ -68,7 +68,7 @@ void GatherParamNames(std::vector<std::string>& p_names, const FuncTypePtr& ft,
// Inspects the given profile to find the i'th parameter (starting at 0).
// Returns nil if the profile indicates that the parameter is not used by the
// function.
const ID* FindParam(int i, const ProfileFunc* pf);
IDPtr FindParam(int i, const ProfileFunc* pf);
// Information associated with a CPPDynStmt dynamic dispatch.
struct DispatchInfo {
@ -92,7 +92,7 @@ std::unordered_map<std::string, std::string> func_index;
// Names for lambda capture ID's. These require a separate space that
// incorporates the lambda's name, to deal with nested lambda's that refer
// to the identifiers with the same name.
std::unordered_map<const ID*, std::string> lambda_names;
std::unordered_map<IDPtr, std::string> lambda_names;
// The function's parameters. Tracked so we don't re-declare them.
IDSet params;

View file

@ -63,8 +63,8 @@ void CPPCompile::Compile(bool report_uncompilable) {
(void)pfs->HashType(t);
rep_types.insert(TypeRep(t));
all_accessed_globals.insert(g.get());
accessed_globals.insert(g.get());
all_accessed_globals.insert(g);
accessed_globals.insert(g);
for ( const auto& i_e : g->GetOptInfo()->GetInitExprs() ) {
auto pf = std::make_shared<ProfileFunc>(i_e.get());

View file

@ -147,7 +147,7 @@ string CPPCompile::GenExpr(const Expr* e, GenType gt, bool top_level) {
string CPPCompile::GenNameExpr(const NameExpr* ne, GenType gt) {
const auto& t = ne->GetType();
auto n = ne->Id();
const auto& n = ne->IdPtr();
bool is_global_var = global_vars.contains(n);
if ( t->Tag() == TYPE_FUNC && ! is_global_var ) {
@ -272,7 +272,7 @@ string CPPCompile::GenCallExpr(const CallExpr* c, GenType gt, bool top_level) {
auto gen = GenExpr(f, GEN_DONT_CARE);
if ( f->Tag() == EXPR_NAME ) {
auto f_id = f->AsNameExpr()->Id();
const auto& f_id = f->AsNameExpr()->IdPtr();
const auto& params = f_id->GetType()->AsFuncType()->Params();
auto id_name = f_id->Name();
auto nargs = args_l->Exprs().length();
@ -1046,7 +1046,7 @@ string CPPCompile::GenAssign(const ExprPtr& lhs, const ExprPtr& rhs, const strin
string CPPCompile::GenDirectAssign(const ExprPtr& lhs, const string& rhs_native, const string& rhs_val_ptr, GenType gt,
bool top_level) {
auto n = lhs->AsNameExpr()->Id();
const auto& n = lhs->AsNameExpr()->IdPtr();
if ( n->IsBlank() )
return rhs_native;
@ -1134,7 +1134,7 @@ string CPPCompile::GenListAssign(const ExprPtr& lhs, const ExprPtr& rhs) {
auto rhs_i = GenericValPtrToGT(rhs_i_base, t_i, GEN_NATIVE);
gen += IDNameStr(var->Id()) + " = " + rhs_i;
gen += IDNameStr(var->IdPtr()) + " = " + rhs_i;
if ( i < n - 1 )
gen += ", ";

View file

@ -195,7 +195,7 @@ void CPPCompile::InitializeGlobals() {
auto& ofiles = analysis_options.only_files;
for ( const auto& ginit : IDOptInfo::GetGlobalInitExprs() ) {
auto g = ginit.Id();
IDPtr g{NewRef{}, const_cast<ID*>(ginit.Id())};
if ( ! ofiles.empty() && ! obj_matches_opt_files(g) )
continue;

View file

@ -331,7 +331,7 @@ AttrInfo::AttrInfo(CPPCompile* _c, const AttrPtr& attr) : CompoundItemInfo(_c) {
}
else if ( a_e->Tag() == EXPR_NAME ) {
auto g = a_e->AsNameExpr()->Id();
auto g = a_e->AsNameExpr()->IdPtr();
gi = c->RegisterGlobal(g);
init_cohort = max(init_cohort, gi->InitCohort() + 1);
@ -363,7 +363,7 @@ AttrsInfo::AttrsInfo(CPPCompile* _c, const AttributesPtr& _attrs) : CompoundItem
}
}
GlobalLookupInitInfo::GlobalLookupInitInfo(CPPCompile* c, const ID* g, string _CPP_name, bool do_init)
GlobalLookupInitInfo::GlobalLookupInitInfo(CPPCompile* c, IDPtr g, string _CPP_name, bool do_init)
: CPP_InitInfo(g), CPP_name(std::move(_CPP_name)) {
Zeek_name = g->Name();
val = ValElem(c, do_init ? g->GetVal() : nullptr);
@ -375,7 +375,7 @@ void GlobalLookupInitInfo::InitializerVals(std::vector<std::string>& ivs) const
ivs.push_back(val);
}
GlobalInitInfo::GlobalInitInfo(CPPCompile* c, const ID* g, string _CPP_name)
GlobalInitInfo::GlobalInitInfo(CPPCompile* c, IDPtr g, string _CPP_name)
: GlobalLookupInitInfo(c, g, std::move(_CPP_name)) {
auto& gt = g->GetType();
auto gi = c->RegisterType(gt);

View file

@ -488,7 +488,7 @@ public:
// then the global will be (re-)initialized to its value during compilation.
class GlobalLookupInitInfo : public CPP_InitInfo {
public:
GlobalLookupInitInfo(CPPCompile* c, const ID* g, std::string CPP_name, bool do_init = false);
GlobalLookupInitInfo(CPPCompile* c, IDPtr g, std::string CPP_name, bool do_init = false);
std::string InitializerType() const override { return "CPP_GlobalLookupInit"; }
void InitializerVals(std::vector<std::string>& ivs) const override;
@ -502,7 +502,7 @@ protected:
// Information for initializing a Zeek global.
class GlobalInitInfo : public GlobalLookupInitInfo {
public:
GlobalInitInfo(CPPCompile* c, const ID* g, std::string CPP_name);
GlobalInitInfo(CPPCompile* c, IDPtr g, std::string CPP_name);
std::string InitializerType() const override { return "CPP_GlobalInit"; }
void InitializerVals(std::vector<std::string>& ivs) const override;

View file

@ -11,7 +11,7 @@ using namespace std;
void CPPCompile::GenStmt(const Stmt* s) {
auto loc = s->GetLocationInfo();
if ( loc != &detail::no_location && s->Tag() != STMT_LIST )
Emit("// %s:%d", loc->FileName(), loc->FirstLine());
Emit("// %s:%s", loc->FileName(), to_string(loc->FirstLine()));
switch ( s->Tag() ) {
case STMT_INIT: GenInitStmt(s->AsInitStmt()); break;
@ -223,7 +223,7 @@ void CPPCompile::GenTypeSwitchStmt(const Expr* e, const case_list* cases) {
Emit("}"); // end the scoping block
}
void CPPCompile::GenTypeSwitchCase(const ID* id, int case_offset, bool is_multi) {
void CPPCompile::GenTypeSwitchCase(const IDPtr id, int case_offset, bool is_multi) {
Emit("case %s:", Fmt(case_offset));
if ( ! id->Name() )
@ -310,13 +310,13 @@ void CPPCompile::GenWhenStmt(const WhenStmt* w) {
for ( auto& l : wi->WhenExprLocals() )
if ( IsAggr(l->GetType()) )
local_aggrs.push_back(IDNameStr(l.get()));
local_aggrs.push_back(IDNameStr(l));
auto when_lambda = GenExpr(wi->Lambda(), GEN_NATIVE);
GenWhenStmt(wi.get(), when_lambda, w->GetLocationInfo(), std::move(local_aggrs));
}
void CPPCompile::GenWhenStmt(const WhenInfo* wi, const std::string& when_lambda, const Location* loc,
void CPPCompile::GenWhenStmt(const WhenInfo* wi, const string& when_lambda, const Location* loc,
vector<string> local_aggrs) {
auto is_return = wi->IsReturn() ? "true" : "false";
auto timeout = wi->TimeoutExpr();
@ -333,7 +333,7 @@ void CPPCompile::GenWhenStmt(const WhenInfo* wi, const std::string& when_lambda,
StartBlock();
Emit("CPP__wi = std::make_shared<WhenInfo>(%s);", is_return);
for ( auto& wg : wi->WhenExprGlobals() )
Emit("CPP__w_globals.insert(find_global__CPP(\"%s\").get());", wg->Name());
Emit("CPP__w_globals.insert(find_global__CPP(\"%s\"));", wg->Name());
EndBlock();
NL();
@ -430,7 +430,8 @@ void CPPCompile::GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var, con
Emit("%s = %s;", IDName(value_var),
GenericValPtrToGT("current_tev__CPP->GetVal()", value_var->GetType(), GEN_NATIVE));
for ( int i = 0; i < loop_vars->length(); ++i ) {
int n = static_cast<int>(loop_vars->size());
for ( int i = 0; i < n; ++i ) {
auto var = (*loop_vars)[i];
if ( var->IsBlank() )
continue;
@ -498,8 +499,8 @@ void CPPCompile::GenAssertStmt(const AssertStmt* a) {
Emit("auto msg_val = zeek::val_mgr->EmptyString();");
auto loc = a->GetLocationInfo();
Emit("static Location loc(\"%s\", %s, %s);", loc->FileName(), std::to_string(loc->FirstLine()),
std::to_string(loc->LastLine()));
Emit("static Location loc(\"%s\", %s, %s);", loc->FileName(), to_string(loc->FirstLine()),
to_string(loc->LastLine()));
Emit("report_assert(assert_result, \"%s\", msg_val, &loc);", CPPEscape(a->CondDesc().c_str()).c_str());
EndBlock();

View file

@ -16,7 +16,7 @@ void GenEventStmt(const EventStmt* ev);
void GenSwitchStmt(const SwitchStmt* sw);
void GenTypeSwitchStmt(const Expr* e, const case_list* cases);
void GenTypeSwitchCase(const ID* id, int case_offset, bool is_multi);
void GenTypeSwitchCase(const IDPtr id, int case_offset, bool is_multi);
void GenValueSwitchStmt(const Expr* e, const case_list* cases);
void GenWhenStmt(const WhenStmt* w);

View file

@ -7,7 +7,7 @@ namespace zeek::detail {
using namespace std;
void CPPCompile::CreateGlobal(const ID* g) {
void CPPCompile::CreateGlobal(IDPtr g) {
auto gn = string(g->Name());
bool is_bif = pfs->BiFGlobals().contains(g);
@ -45,7 +45,7 @@ void CPPCompile::CreateGlobal(const ID* g) {
global_vars.emplace(g);
}
std::shared_ptr<CPP_InitInfo> CPPCompile::RegisterGlobal(const ID* g) {
std::shared_ptr<CPP_InitInfo> CPPCompile::RegisterGlobal(IDPtr g) {
auto gg = global_gis.find(g);
if ( gg != global_gis.end() )
@ -71,7 +71,7 @@ std::shared_ptr<CPP_InitInfo> CPPCompile::RegisterGlobal(const ID* g) {
return gi;
}
std::shared_ptr<CPP_InitInfo> CPPCompile::GenerateGlobalInit(const ID* g) {
std::shared_ptr<CPP_InitInfo> CPPCompile::GenerateGlobalInit(IDPtr g) {
auto gn = string(g->Name());
if ( ! standalone )
return make_shared<GlobalLookupInitInfo>(this, g, globals[gn]);
@ -94,7 +94,7 @@ std::shared_ptr<CPP_InitInfo> CPPCompile::GenerateGlobalInit(const ID* g) {
return make_shared<GlobalLookupInitInfo>(this, g, globals[gn], needs_redef);
}
void CPPCompile::AddBiF(const ID* b, bool is_var) {
void CPPCompile::AddBiF(IDPtr b, bool is_var) {
auto bn = b->Name();
auto n = string(bn);
if ( is_var )
@ -117,7 +117,7 @@ bool CPPCompile::AddGlobal(const string& g, const char* suffix) {
void CPPCompile::RegisterEvent(string ev_name) { body_events[body_name].emplace_back(std::move(ev_name)); }
const string& CPPCompile::IDNameStr(const ID* id) {
const string& CPPCompile::IDNameStr(const IDPtr& id) {
if ( id->IsGlobal() ) {
auto g = string(id->Name());
if ( ! globals.contains(g) )
@ -130,7 +130,7 @@ const string& CPPCompile::IDNameStr(const ID* id) {
return l->second;
}
static string trim_name(const ID* id) {
static string trim_name(const IDPtr& id) {
auto n = id->Name();
auto without_module = strstr(n, "::");
@ -152,9 +152,9 @@ static string trim_name(const ID* id) {
return ns;
}
string CPPCompile::LocalName(const ID* l) const { return Canonicalize(trim_name(l)); }
string CPPCompile::LocalName(const IDPtr& l) const { return Canonicalize(trim_name(l)); }
string CPPCompile::CaptureName(const ID* c) const {
string CPPCompile::CaptureName(const IDPtr& c) const {
// We want to strip both the module and any inlining appendage.
auto tn = trim_name(c);

View file

@ -7,20 +7,20 @@
public:
// Tracks a global to generate the necessary initialization.
// Returns the associated initialization info.
std::shared_ptr<CPP_InitInfo> RegisterGlobal(const ID* g);
std::shared_ptr<CPP_InitInfo> RegisterGlobal(IDPtr g);
private:
// Generate declarations associated with the given global, and, if it's used
// as a variable (not just as a function being called), track it as such.
void CreateGlobal(const ID* g);
void CreateGlobal(IDPtr g);
// Low-level function for generating an initializer for a global. Takes
// into account differences for standalone-compilation.
std::shared_ptr<CPP_InitInfo> GenerateGlobalInit(const ID* g);
std::shared_ptr<CPP_InitInfo> GenerateGlobalInit(IDPtr g);
// Register the given identifier as a BiF. If is_var is true then the BiF
// is also used in a non-call context.
void AddBiF(const ID* b, bool is_var);
void AddBiF(IDPtr b, bool is_var);
// Register the given global name. "suffix" distinguishes particular types
// of globals, such as the names of bifs, global (non-function) variables,
@ -32,9 +32,8 @@ void RegisterEvent(std::string ev_name);
// The following match various forms of identifiers to the name used for
// their C++ equivalent.
const char* IDName(const IDPtr& id) { return IDName(id.get()); }
const char* IDName(const ID* id) { return IDNameStr(id).c_str(); }
const std::string& IDNameStr(const ID* id);
const char* IDName(const IDPtr& id) { return IDNameStr(id).c_str(); }
const std::string& IDNameStr(const IDPtr& id);
// Returns a canonicalized version of a variant of a global made distinct by
// the given suffix.
@ -42,12 +41,10 @@ std::string GlobalName(const std::string& g, const char* suffix) { return Canoni
// Returns a canonicalized form of a local identifier's name, expanding its
// module prefix if needed.
std::string LocalName(const ID* l) const;
std::string LocalName(const IDPtr& l) const { return LocalName(l.get()); }
std::string LocalName(const IDPtr& l) const;
// The same, but for a capture.
std::string CaptureName(const ID* l) const;
std::string CaptureName(const IDPtr& l) const { return CaptureName(l.get()); }
std::string CaptureName(const IDPtr& l) const;
// Returns a canonicalized name, with various non-alphanumeric characters
// stripped or transformed, and guaranteed not to conflict with C++ keywords.
@ -59,10 +56,10 @@ std::string GlobalName(const ExprPtr& e) { return globals[e->AsNameExpr()->Id()-
// Globals that are used (appear in the profiles) of the bodies we're
// compiling. Includes globals just used as functions to call.
std::unordered_set<const ID*> all_accessed_globals;
std::unordered_set<IDPtr> all_accessed_globals;
// Same, but just the globals used in contexts beyond function calls.
std::unordered_set<const ID*> accessed_globals;
std::unordered_set<IDPtr> accessed_globals;
// Lambdas that are accessed.
std::unordered_set<const LambdaExpr*> accessed_lambdas;
@ -74,10 +71,10 @@ std::unordered_set<std::string> accessed_events;
std::unordered_map<std::string, std::string> globals;
// Similar for locals, for the function currently being compiled.
std::unordered_map<const ID*, std::string> locals;
std::unordered_map<IDPtr, std::string> locals;
// Retrieves the initialization information associated with the given global.
std::unordered_map<const ID*, std::shared_ptr<CPP_InitInfo>> global_gis;
std::unordered_map<IDPtr, std::shared_ptr<CPP_InitInfo>> global_gis;
// Maps event names to the names we use for them.
std::unordered_map<std::string, std::string> events;

View file

@ -6,7 +6,7 @@
namespace zeek::detail {
CSE_ValidityChecker::CSE_ValidityChecker(std::shared_ptr<ProfileFuncs> _pfs, const std::vector<const ID*>& _ids,
CSE_ValidityChecker::CSE_ValidityChecker(std::shared_ptr<ProfileFuncs> _pfs, const std::vector<IDPtr>& _ids,
const Expr* _start_e, const Expr* _end_e)
: pfs(std::move(_pfs)), ids(_ids) {
start_e = _start_e;
@ -111,7 +111,7 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) {
auto lhs_ref = e->GetOp1()->AsRefExprPtr();
auto lhs = lhs_ref->GetOp1()->AsNameExpr();
if ( CheckID(lhs->Id(), false) )
if ( CheckID(lhs->IdPtr(), false) )
return TC_ABORTALL;
// Note, we don't use CheckAggrMod() because this is a plain
@ -127,7 +127,7 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) {
case EXPR_INDEX_ASSIGN: {
auto lhs_aggr = e->GetOp1();
auto lhs_aggr_id = lhs_aggr->AsNameExpr()->Id();
const auto& lhs_aggr_id = lhs_aggr->AsNameExpr()->IdPtr();
if ( CheckID(lhs_aggr_id, true) || CheckTableMod(lhs_aggr->GetType()) )
return TC_ABORTALL;
@ -135,7 +135,7 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) {
case EXPR_FIELD_LHS_ASSIGN: {
auto lhs = e->GetOp1();
auto lhs_aggr_id = lhs->AsNameExpr()->Id();
const auto& lhs_aggr_id = lhs->AsNameExpr()->IdPtr();
auto lhs_field = static_cast<const FieldLHSAssignExpr*>(e)->Field();
if ( CheckID(lhs_aggr_id, true) )
@ -186,7 +186,7 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) {
auto aggr_t = aggr->GetType();
if ( in_aggr_mod_expr > 0 ) {
auto aggr_id = aggr->AsNameExpr()->Id();
const auto& aggr_id = aggr->AsNameExpr()->IdPtr();
if ( CheckID(aggr_id, true) || CheckAggrMod(aggr_t) )
return TC_ABORTALL;
@ -211,7 +211,7 @@ TraversalCode CSE_ValidityChecker::PostExpr(const Expr* e) {
return TC_CONTINUE;
}
bool CSE_ValidityChecker::CheckID(const ID* id, bool ignore_orig) {
bool CSE_ValidityChecker::CheckID(const IDPtr& id, bool ignore_orig) {
for ( auto i : ids ) {
if ( ignore_orig && i == ids.front() )
continue;

View file

@ -17,7 +17,7 @@ class TempVar;
class CSE_ValidityChecker : public TraversalCallback {
public:
CSE_ValidityChecker(std::shared_ptr<ProfileFuncs> pfs, const std::vector<const ID*>& ids, const Expr* start_e,
CSE_ValidityChecker(std::shared_ptr<ProfileFuncs> pfs, const std::vector<IDPtr>& ids, const Expr* start_e,
const Expr* end_e);
TraversalCode PreStmt(const Stmt*) override;
@ -45,7 +45,7 @@ public:
protected:
// Returns true if an assignment involving the given identifier on
// the LHS is in conflict with the identifiers we're tracking.
bool CheckID(const ID* id, bool ignore_orig);
bool CheckID(const IDPtr& id, bool ignore_orig);
// Returns true if a modification to an aggregate of the given type
// potentially aliases with one of the identifiers we're tracking.
@ -83,7 +83,7 @@ protected:
// The list of identifiers for which an assignment to one of them
// renders the CSE unsafe.
const std::vector<const ID*>& ids;
const std::vector<IDPtr>& ids;
// Where in the AST to start our analysis. This is the initial
// assignment expression.

View file

@ -112,7 +112,7 @@ TraversalCode GenIDDefs::PreStmt(const Stmt* s) {
auto retvar = cr->RetVar();
if ( retvar )
TrackID(retvar->Id());
TrackID(retvar->IdPtr());
return TC_ABORTSTMT;
}
@ -278,7 +278,7 @@ TraversalCode GenIDDefs::PreExpr(const Expr* e) {
e->GetOptInfo()->stmt_num = stmt_num;
switch ( e->Tag() ) {
case EXPR_NAME: CheckVarUsage(e, e->AsNameExpr()->Id()); break;
case EXPR_NAME: CheckVarUsage(e, e->AsNameExpr()->IdPtr()); break;
case EXPR_ASSIGN: {
auto lhs = e->GetOp1();
@ -358,7 +358,7 @@ bool GenIDDefs::CheckLHS(const ExprPtr& lhs, const ExprPtr& rhs) {
case EXPR_NAME: {
auto n = lhs->AsNameExpr();
TrackID(n->Id(), rhs);
TrackID(n->IdPtr(), rhs);
return true;
}
@ -371,7 +371,7 @@ bool GenIDDefs::CheckLHS(const ExprPtr& lhs, const ExprPtr& rhs) {
return false;
auto n = expr->AsNameExpr();
TrackID(n->Id());
TrackID(n->IdPtr());
}
return true;
@ -400,7 +400,7 @@ bool GenIDDefs::IsAggr(const Expr* e) const {
return zeek::IsAggr(tag);
}
void GenIDDefs::CheckVarUsage(const Expr* e, const ID* id) {
void GenIDDefs::CheckVarUsage(const Expr* e, const IDPtr& id) {
if ( analysis_options.usage_issues != 1 || id->IsGlobal() || suppress_usage > 0 )
return;
@ -483,7 +483,7 @@ void GenIDDefs::ReturnAt(const Stmt* s) {
id->GetOptInfo()->ReturnAt(s);
}
void GenIDDefs::TrackID(const ID* id, const ExprPtr& e) {
void GenIDDefs::TrackID(const IDPtr& id, const ExprPtr& e) {
auto oi = id->GetOptInfo();
// The 4th argument here is hardwired to 0, meaning "assess across all

View file

@ -39,7 +39,7 @@ private:
// If -u is active, checks for whether the given identifier present
// in the given expression is undefined at that point.
void CheckVarUsage(const Expr* e, const ID* id);
void CheckVarUsage(const Expr* e, const IDPtr& id);
// Begin a new confluence block with the given statement.
void StartConfluenceBlock(const Stmt* s);
@ -70,8 +70,7 @@ private:
// statement in the current confluence block. 'e' is the
// expression used to define the identifier, for simple direct
// assignments.
void TrackID(const IDPtr& id, const ExprPtr& e = nullptr) { TrackID(id.get(), e); }
void TrackID(const ID* id, const ExprPtr& e = nullptr);
void TrackID(const IDPtr& id, const ExprPtr& e = nullptr);
// Profile for the function. Currently, all we actually need from
// this is the list of globals and locals.

View file

@ -35,7 +35,7 @@ ProfileFunc::ProfileFunc(const Func* func, const StmtPtr& body, bool _abs_rec_fi
int offset = 0;
for ( auto& c : *fcaps ) {
auto cid = c.Id().get();
auto cid = c.Id();
captures.insert(cid);
captures_offsets[cid] = offset++;
}
@ -88,7 +88,7 @@ ProfileFunc::ProfileFunc(const Expr* e, bool _abs_rec_fields) {
auto& ov = profiled_scope->OrderedVars();
for ( int i = 0; i < num_params; ++i )
params.insert(ov[i].get());
params.insert(ov[i]);
TrackType(ft);
body->Traverse(this);
@ -106,7 +106,7 @@ TraversalCode ProfileFunc::PreStmt(const Stmt* s) {
switch ( s->Tag() ) {
case STMT_INIT:
for ( const auto& id : s->AsInitStmt()->Inits() ) {
inits.insert(id.get());
inits.insert(id);
auto& t = id->GetType();
TrackType(t);
@ -143,7 +143,7 @@ TraversalCode ProfileFunc::PreStmt(const Stmt* s) {
locals.insert(id);
if ( value_var )
locals.insert(value_var.get());
locals.insert(value_var);
} break;
case STMT_SWITCH: {
@ -194,7 +194,7 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
case EXPR_NAME: {
auto n = e->AsNameExpr();
auto id = n->Id();
auto id = n->IdPtr();
// Turns out that NameExpr's can be constructed using a
// different Type* than that of the identifier itself,
@ -202,7 +202,7 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
TrackType(id->GetType());
if ( id->IsGlobal() ) {
PreID(id);
PreID(id.get());
break;
}
@ -256,7 +256,7 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
auto& rhs_id = rhs->AsNameExpr()->IdPtr();
const auto& t = rhs_id->GetType();
if ( t->Tag() == TYPE_FUNC && t->AsFuncType()->Flavor() == FUNC_FLAVOR_FUNCTION )
indirect_funcs.insert(rhs_id.get());
indirect_funcs.insert(rhs_id);
}
}
@ -272,7 +272,7 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
switch ( lhs->Tag() ) {
case EXPR_NAME: {
auto id = lhs->AsNameExpr()->Id();
auto id = lhs->AsNameExpr()->IdPtr();
TrackAssignment(id);
if ( is_assign ) {
@ -346,11 +346,11 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
auto f = c->Func();
const NameExpr* n = nullptr;
const ID* func = nullptr;
IDPtr func;
if ( f->Tag() == EXPR_NAME ) {
n = f->AsNameExpr();
func = n->Id();
func = n->IdPtr();
if ( ! func->IsGlobal() )
does_indirect_calls = true;
@ -367,7 +367,7 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
auto& arg_id = arg->AsNameExpr()->IdPtr();
const auto& t = arg_id->GetType();
if ( t->Tag() == TYPE_FUNC && t->AsFuncType()->Flavor() == FUNC_FLAVOR_FUNCTION )
indirect_funcs.insert(arg_id.get());
indirect_funcs.insert(arg_id);
}
}
@ -482,8 +482,8 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
return TC_CONTINUE;
}
TraversalCode ProfileFunc::PreID(const ID* id) {
TrackID(id);
TraversalCode ProfileFunc::PreID(const ID* id_raw) {
IDPtr id{NewRef{}, const_cast<ID*>(id_raw)};
if ( id->IsGlobal() ) {
globals.insert(id);
@ -521,7 +521,7 @@ void ProfileFunc::TrackType(const Type* t) {
ordered_types.push_back(t);
}
void ProfileFunc::TrackID(const ID* id) {
void ProfileFunc::TrackID(const IDPtr id) {
if ( ! id )
return;
@ -540,8 +540,8 @@ void ProfileFunc::TrackID(const ID* id) {
ordered_ids.push_back(id);
}
void ProfileFunc::TrackAssignment(const ID* id) {
if ( assignees.contains(id) )
void ProfileFunc::TrackAssignment(const IDPtr id) {
if ( assignees.count(id) > 0 )
++assignees[id];
else
assignees[id] = 1;

View file

@ -98,7 +98,7 @@ public:
const auto& CapturesOffsets() const { return captures_offsets; }
const IDSet& WhenLocals() const { return when_locals; }
const IDSet& Params() const { return params; }
const std::unordered_map<const ID*, int>& Assignees() const { return assignees; }
const std::unordered_map<IDPtr, int>& Assignees() const { return assignees; }
const IDSet& NonLocalAssignees() const { return non_local_assignees; }
const auto& TableRefs() const { return tbl_refs; }
const auto& AggrMods() const { return aggr_mods; }
@ -108,7 +108,7 @@ public:
const std::vector<const LambdaExpr*>& Lambdas() const { return lambdas; }
const std::vector<const ConstExpr*>& Constants() const { return constants; }
const IDSet& UnorderedIdentifiers() const { return ids; }
const std::vector<const ID*>& OrderedIdentifiers() const { return ordered_ids; }
const std::vector<IDPtr>& OrderedIdentifiers() const { return ordered_ids; }
const TypeSet& UnorderedTypes() const { return types; }
const std::vector<const Type*>& OrderedTypes() const { return ordered_types; }
const auto& TypeAliases() const { return type_aliases; }
@ -153,10 +153,10 @@ protected:
void TrackType(const TypePtr& t) { TrackType(t.get()); }
// Take note of the presence of an identifier.
void TrackID(const ID* id);
void TrackID(IDPtr id);
// Take note of an assignment to an identifier.
void TrackAssignment(const ID* id);
void TrackAssignment(IDPtr id);
// Extracts attributes of a record type used in a constructor (or implicit
// initialization, or coercion, which does an implicit construction).
@ -198,7 +198,7 @@ protected:
// they are assigned to (no entry if never). Does not include
// implicit assignments due to initializations, which are instead
// captured in "inits".
std::unordered_map<const ID*, int> assignees;
std::unordered_map<IDPtr, int> assignees;
// A subset of assignees reflecting those that are globals or captures.
IDSet non_local_assignees;
@ -230,7 +230,7 @@ protected:
IDSet captures;
// This maps capture identifiers to their offsets.
std::map<const ID*, int> captures_offsets;
std::unordered_map<IDPtr, int> captures_offsets;
// Constants seen in the function.
std::vector<const ConstExpr*> constants;
@ -239,7 +239,7 @@ protected:
IDSet ids;
// The same, but in a deterministic order.
std::vector<const ID*> ordered_ids;
std::vector<IDPtr> ordered_ids;
// Types seen in the function. A set rather than a vector because
// the same type can be seen numerous times.

View file

@ -239,12 +239,12 @@ Reducer::Reducer(const ScriptFuncPtr& func, std::shared_ptr<ProfileFunc> _pf, st
auto& scope_vars = current_scope()->OrderedVars();
for ( auto i = 0; i < num_params; ++i )
tracked_ids.insert(scope_vars[i].get());
tracked_ids.insert(scope_vars[i]);
// Now include any captures.
if ( ft->GetCaptures() )
for ( auto& c : *ft->GetCaptures() )
tracked_ids.insert(c.Id().get());
tracked_ids.insert(c.Id());
}
StmtPtr Reducer::Reduce(StmtPtr s) {
@ -275,17 +275,12 @@ NameExprPtr Reducer::UpdateName(NameExprPtr n) {
return ne;
}
bool Reducer::NameIsReduced(const NameExpr* n) { return ID_IsReducedOrTopLevel(n->Id()); }
bool Reducer::NameIsReduced(const NameExpr* n) { return ID_IsReducedOrTopLevel(n->IdPtr()); }
void Reducer::UpdateIDs(IDPList* ids) {
loop_over_list(*ids, i) {
IDPtr id = {NewRef{}, (*ids)[i]};
if ( ! ID_IsReducedOrTopLevel(id) ) {
Unref((*ids)[i]);
(*ids)[i] = UpdateID(id).release();
}
}
for ( auto& id : *ids )
if ( ! ID_IsReducedOrTopLevel(id) )
id = UpdateID(id);
}
void Reducer::UpdateIDs(std::vector<IDPtr>& ids) {
@ -317,7 +312,7 @@ IDPtr Reducer::UpdateID(IDPtr id) {
return FindNewLocal(id);
}
bool Reducer::ID_IsReducedOrTopLevel(const ID* id) {
bool Reducer::ID_IsReducedOrTopLevel(const IDPtr& id) {
if ( inline_block_level == 0 ) {
tracked_ids.insert(id);
return true;
@ -326,8 +321,8 @@ bool Reducer::ID_IsReducedOrTopLevel(const ID* id) {
return ID_IsReduced(id);
}
bool Reducer::ID_IsReduced(const ID* id) const {
return inline_block_level == 0 || tracked_ids.contains(id) || id->IsGlobal() || IsTemporary(id);
bool Reducer::ID_IsReduced(const IDPtr& id) const {
return inline_block_level == 0 || tracked_ids.count(id) > 0 || id->IsGlobal() || IsTemporary(id);
}
StmtPtr Reducer::GenParam(const IDPtr& id, ExprPtr rhs, bool is_modified) {
@ -352,14 +347,14 @@ StmtPtr Reducer::GenParam(const IDPtr& id, ExprPtr rhs, bool is_modified) {
// Can use a temporary variable, which then supports
// optimization via alias propagation.
auto param_id = GenTemporary(id->GetType(), rhs, param->IdPtr());
auto& tv = ids_to_temps[param_id.get()];
auto& tv = ids_to_temps[param_id];
if ( rhs_id )
tv->SetAlias(rhs_id);
else if ( rhs->Tag() == EXPR_CONST )
tv->SetConst(rhs->AsConstExpr());
param_temps.insert(param_id.get());
param_temps.insert(param_id);
param = make_intrusive<NameExpr>(param_id);
param->SetLocationInfo(rhs->GetLocationInfo());
}
@ -402,7 +397,7 @@ NameExprPtr Reducer::GetRetVar(TypePtr type) {
ret_id->SetType(std::move(type));
ret_id->GetOptInfo()->SetTemp();
ret_vars.insert(ret_id.get());
ret_vars.insert(ret_id);
// Track this as a new local *if* we're in the outermost inlining
// block. If we're recursively deeper into inlining, then this
@ -442,7 +437,7 @@ IDPtr Reducer::FindExprTmp(const Expr* rhs, const Expr* a, const std::shared_ptr
if ( same_expr(rhs, et_i_expr, true) ) {
// We have an apt candidate. Make sure its value
// always makes it here.
auto id = et_i->Id().get();
const auto& id = et_i->Id();
auto stmt_num = a->GetOptInfo()->stmt_num;
auto def = id->GetOptInfo()->DefinitionBefore(stmt_num);
@ -464,7 +459,7 @@ IDPtr Reducer::FindExprTmp(const Expr* rhs, const Expr* a, const std::shared_ptr
return nullptr;
}
bool Reducer::ExprValid(const ID* id, const Expr* e1, const Expr* e2) const {
bool Reducer::ExprValid(const IDPtr& id, const Expr* e1, const Expr* e2) const {
// First check for whether e1 is already known to itself have side effects.
// If so, then it's never safe to reuse its associated identifier in lieu
// of e2.
@ -522,17 +517,17 @@ bool Reducer::ExprValid(const ID* id, const Expr* e1, const Expr* e2) const {
// of script functions.
// Tracks which ID's are germane for our analysis.
std::vector<const ID*> ids;
std::vector<IDPtr> ids;
ids.push_back(id);
ids.push_back(std::move(id));
// Identify variables involved in the expression.
CheckIDs(e1->GetOp1().get(), ids);
CheckIDs(e1->GetOp2().get(), ids);
CheckIDs(e1->GetOp3().get(), ids);
CheckIDs(e1->GetOp1(), ids);
CheckIDs(e1->GetOp2(), ids);
CheckIDs(e1->GetOp3(), ids);
if ( e1->Tag() == EXPR_NAME )
ids.push_back(e1->AsNameExpr()->Id());
ids.push_back(e1->AsNameExpr()->IdPtr());
CSE_ValidityChecker vc(pfs, ids, e1, e2);
reduction_root->Traverse(&vc);
@ -540,22 +535,22 @@ bool Reducer::ExprValid(const ID* id, const Expr* e1, const Expr* e2) const {
return vc.IsValid();
}
void Reducer::CheckIDs(const Expr* e, std::vector<const ID*>& ids) const {
void Reducer::CheckIDs(const ExprPtr& e, std::vector<IDPtr>& ids) const {
if ( ! e )
return;
if ( e->Tag() == EXPR_LIST ) {
const auto& e_l = e->AsListExpr()->Exprs();
for ( auto i = 0; i < e_l.length(); ++i )
CheckIDs(e_l[i], ids);
CheckIDs({NewRef{}, e_l[i]}, ids);
}
else if ( e->Tag() == EXPR_NAME )
ids.push_back(e->AsNameExpr()->Id());
ids.push_back(e->AsNameExpr()->IdPtr());
}
bool Reducer::IsCSE(const AssignExpr* a, const NameExpr* lhs, const Expr* rhs) {
auto lhs_id = lhs->Id();
auto lhs_id = lhs->IdPtr();
auto lhs_tmp = FindTemporary(lhs_id); // nil if LHS not a temporary
auto rhs_tmp = FindExprTmp(rhs, a, lhs_tmp);
@ -572,8 +567,8 @@ bool Reducer::IsCSE(const AssignExpr* a, const NameExpr* lhs, const Expr* rhs) {
}
if ( rhs->Tag() == EXPR_NAME ) {
auto rhs_id = rhs->AsNameExpr()->IdPtr();
auto rhs_tmp_var = FindTemporary(rhs_id.get());
const auto& rhs_id = rhs->AsNameExpr()->IdPtr();
auto rhs_tmp_var = FindTemporary(rhs_id);
if ( rhs_tmp_var ) {
if ( rhs_tmp_var->Const() )
@ -659,16 +654,15 @@ ExprPtr Reducer::UpdateExpr(ExprPtr e) {
return OptExpr(e);
auto n = e->AsNameExpr();
auto id = n->Id();
const auto& id = n->IdPtr();
if ( id->IsGlobal() )
return e;
auto tmp_var = FindTemporary(id);
if ( ! tmp_var ) {
IDPtr id_ptr = {NewRef{}, id};
auto stmt_num = e->GetOptInfo()->stmt_num;
auto is_const = CheckForConst(id_ptr, stmt_num);
auto is_const = CheckForConst(id, stmt_num);
if ( is_const ) {
// Remember this variable as one whose value
@ -690,12 +684,12 @@ ExprPtr Reducer::UpdateExpr(ExprPtr e) {
if ( alias ) {
// Make sure that the definitions for the alias here are
// the same as when the alias was created.
auto alias_tmp = FindTemporary(alias.get());
auto alias_tmp = FindTemporary(alias);
// Resolve any alias chains.
while ( alias_tmp && alias_tmp->Alias() ) {
alias = alias_tmp->Alias();
alias_tmp = FindTemporary(alias.get());
alias_tmp = FindTemporary(alias);
}
return NewVarUsage(alias, e.get());
@ -711,7 +705,7 @@ ExprPtr Reducer::UpdateExpr(ExprPtr e) {
StmtPtr Reducer::MergeStmts(const NameExpr* lhs, ExprPtr rhs, const StmtPtr& succ_stmt) {
// First check for tmp=rhs.
auto lhs_id = lhs->Id();
auto lhs_id = lhs->IdPtr();
auto lhs_tmp = FindTemporary(lhs_id);
if ( ! lhs_tmp )
@ -738,8 +732,8 @@ StmtPtr Reducer::MergeStmts(const NameExpr* lhs, ExprPtr rhs, const StmtPtr& suc
// Complex 2nd-statement assignment.
return nullptr;
auto a_lhs_var = a_lhs_deref->AsNameExpr()->Id();
auto a_rhs_var = a_rhs->AsNameExpr()->Id();
const auto& a_lhs_var = a_lhs_deref->AsNameExpr()->IdPtr();
const auto& a_rhs_var = a_rhs->AsNameExpr()->IdPtr();
if ( a_rhs_var != lhs_id )
// 2nd statement is var=something else.
@ -794,13 +788,13 @@ IDPtr Reducer::GenTemporary(TypePtr t, ExprPtr rhs, IDPtr id) {
temps.push_back(temp);
om.AddObj(temp_id.get());
ids_to_temps[temp_id.get()] = temp;
ids_to_temps[temp_id] = temp;
return temp_id;
}
IDPtr Reducer::FindNewLocal(const IDPtr& id) {
auto mapping = orig_to_new_locals.find(id.get());
auto mapping = orig_to_new_locals.find(id);
if ( mapping != orig_to_new_locals.end() )
return mapping->second;
@ -809,8 +803,8 @@ IDPtr Reducer::FindNewLocal(const IDPtr& id) {
}
void Reducer::AddNewLocal(const IDPtr& l) {
new_locals.insert(l.get());
tracked_ids.insert(l.get());
new_locals.insert(l);
tracked_ids.insert(l);
}
IDPtr Reducer::GenLocal(const IDPtr& orig) {
@ -838,25 +832,22 @@ IDPtr Reducer::GenLocal(const IDPtr& orig) {
local_id->GetOptInfo()->SetTemp();
IDPtr prev;
if ( orig_to_new_locals.contains(orig.get()) )
prev = orig_to_new_locals[orig.get()];
if ( orig_to_new_locals.count(orig) )
prev = orig_to_new_locals[orig];
AddNewLocal(local_id);
om.AddObj(orig.get());
orig_to_new_locals[orig.get()] = local_id;
orig_to_new_locals[orig] = local_id;
if ( ! block_locals.empty() && ! ret_vars.contains(orig.get()) )
block_locals.back()[orig.get()] = prev;
if ( ! block_locals.empty() && ret_vars.count(orig) == 0 )
block_locals.back()[orig] = prev;
return local_id;
}
bool Reducer::IsNewLocal(const ID* id) const {
ID* non_const_ID = (ID*)id; // I don't get why C++ requires this
return new_locals.contains(non_const_ID);
}
bool Reducer::IsNewLocal(const IDPtr& id) const { return new_locals.count(id) != 0; }
std::shared_ptr<TempVar> Reducer::FindTemporary(const ID* id) const {
std::shared_ptr<TempVar> Reducer::FindTemporary(const IDPtr& id) const {
auto tmp = ids_to_temps.find(id);
if ( tmp == ids_to_temps.end() )
return nullptr;

View file

@ -34,12 +34,10 @@ public:
bool IDsAreReduced(const std::vector<IDPtr>& ids) const;
IDPtr UpdateID(IDPtr id);
bool ID_IsReduced(const IDPtr& id) const { return ID_IsReduced(id.get()); }
bool ID_IsReduced(const ID* id) const;
bool ID_IsReduced(const IDPtr& id) const;
// A version of ID_IsReduced() that tracks top-level variables, too.
bool ID_IsReducedOrTopLevel(const IDPtr& id) { return ID_IsReducedOrTopLevel(id.get()); }
bool ID_IsReducedOrTopLevel(const ID* id);
bool ID_IsReducedOrTopLevel(const IDPtr& id);
// This is called *prior* to pushing a new inline block, in order
// to generate the equivalent of function parameters. "rhs" is
@ -79,13 +77,13 @@ public:
int NumTemps() const { return temps.size(); }
// True if this name already reflects the replacement.
bool IsNewLocal(const NameExpr* n) const { return IsNewLocal(n->Id()); }
bool IsNewLocal(const ID* id) const;
bool IsNewLocal(const NameExpr* n) const { return IsNewLocal(n->IdPtr()); }
bool IsNewLocal(const IDPtr& id) const;
bool IsTemporary(const ID* id) const { return FindTemporary(id) != nullptr; }
bool IsParamTemp(const ID* id) const { return param_temps.contains(id); }
bool IsTemporary(const IDPtr& id) const { return FindTemporary(id) != nullptr; }
bool IsParamTemp(const IDPtr& id) const { return param_temps.count(id) > 0; }
bool IsConstantVar(const ID* id) const { return constant_vars.contains(id); }
bool IsConstantVar(const IDPtr& id) const { return constant_vars.find(id) != constant_vars.end(); }
// True if the Reducer is being used in the context of a second
// pass over for AST optimization.
@ -183,16 +181,16 @@ protected:
// Tests whether an expression computed at e1 (and assigned to "id")
// remains valid for substitution at e2.
bool ExprValid(const ID* id, const Expr* e1, const Expr* e2) const;
bool ExprValid(const IDPtr& id, const Expr* e1, const Expr* e2) const;
// Inspects the given expression for identifiers, adding any
// observed to the given vector. Assumes reduced form, so only
// NameExpr's and ListExpr's are of interest - does not traverse
// into compound expressions.
void CheckIDs(const Expr* e, std::vector<const ID*>& ids) const;
void CheckIDs(const ExprPtr& e, std::vector<IDPtr>& ids) const;
IDPtr GenTemporary(TypePtr t, ExprPtr rhs, IDPtr id = nullptr);
std::shared_ptr<TempVar> FindTemporary(const ID* id) const;
std::shared_ptr<TempVar> FindTemporary(const IDPtr& id) const;
// Retrieve the identifier corresponding to the new local for
// the given expression. Creates the local if necessary.
@ -228,7 +226,7 @@ protected:
// Lets us go from an identifier to an associated temporary
// variable, if it corresponds to one.
std::unordered_map<const ID*, std::shared_ptr<TempVar>> ids_to_temps;
std::unordered_map<IDPtr, std::shared_ptr<TempVar>> ids_to_temps;
// Identifiers that we're tracking (and don't want to replace).
IDSet tracked_ids;
@ -242,7 +240,7 @@ protected:
// Mapping of original identifiers to new locals. Used to
// rename local variables when inlining.
std::unordered_map<const ID*, IDPtr> orig_to_new_locals;
std::unordered_map<IDPtr, IDPtr> orig_to_new_locals;
// Tracks expressions we've folded, so that we can recognize them
// for constant propagation.
@ -269,7 +267,7 @@ protected:
// Tracks locals introduced in the current block, remembering
// their previous replacement value (per "orig_to_new_locals"),
// if any. When we pop the block, we restore the previous mapping.
std::vector<std::unordered_map<const ID*, IDPtr>> block_locals;
std::vector<std::unordered_map<IDPtr, IDPtr>> block_locals;
// Memory management for AST elements that might change during
// the reduction/optimization processes.

View file

@ -371,10 +371,8 @@ IntrusivePtr<Case> Case::Duplicate() {
if ( type_cases ) {
new_type_cases = new IDPList();
for ( auto tc : *type_cases ) {
zeek::Ref(tc);
new_type_cases->append(tc);
}
for ( auto tc : *type_cases )
new_type_cases->emplace_back(std::move(tc));
}
return make_intrusive<Case>(nullptr, new_type_cases, s->Duplicate());
@ -439,9 +437,9 @@ StmtPtr SwitchStmt::DoReduce(Reducer* rc) {
// Update type cases.
for ( auto& i : case_label_type_list ) {
IDPtr idp = {NewRef{}, i.first};
if ( idp->Name() )
i.first = rc->UpdateID(idp).release();
auto& id = i.first;
if ( id->Name() )
id = rc->UpdateID(id);
}
for ( const auto& c : *cases ) {
@ -458,7 +456,7 @@ StmtPtr SwitchStmt::DoReduce(Reducer* rc) {
if ( c_t ) {
for ( auto& c_t_i : *c_t )
if ( c_t_i->Name() )
c_t_i = rc->UpdateID({NewRef{}, c_t_i}).release();
c_t_i = rc->UpdateID(c_t_i);
}
c->UpdateBody(c->Body()->Reduce(rc));
@ -479,7 +477,7 @@ bool SwitchStmt::NoFlowAfter(bool ignore_break) const {
return false;
if ( (! c->ExprCases() || c->ExprCases()->Exprs().length() == 0) &&
(! c->TypeCases() || c->TypeCases()->length() == 0) )
(! c->TypeCases() || c->TypeCases()->empty()) )
// We saw the default, and the test before this
// one established that it has no flow after it.
default_seen_with_no_flow_after = true;
@ -570,12 +568,9 @@ bool WhileStmt::CouldReturn(bool ignore_break) const { return body->CouldReturn(
StmtPtr ForStmt::Duplicate() {
auto expr_copy = e->Duplicate();
auto new_loop_vars = new zeek::IDPList;
loop_over_list(*loop_vars, i) {
auto id = (*loop_vars)[i];
zeek::Ref(id);
new_loop_vars->append(id);
}
auto new_loop_vars = new IDPList;
for ( auto id : *loop_vars )
new_loop_vars->emplace_back(std::move(id));
ForStmt* f;
if ( value_var )
@ -798,7 +793,7 @@ static unsigned int find_rec_assignment_chain(const std::vector<StmtPtr>& stmts,
return i;
}
using OpChain = std::map<const ID*, std::vector<const Stmt*>>;
using OpChain = std::unordered_map<IDPtr, std::vector<const Stmt*>>;
static void update_assignment_chains(const StmtPtr& s, OpChain& assign_chains, OpChain& add_chains) {
auto se = s->AsExprStmt()->StmtExpr();
@ -854,7 +849,7 @@ static void update_assignment_chains(const StmtPtr& s, OpChain& assign_chains, O
return;
// If we get here, it's a keeper, record the associated statement.
auto id = f_rec->AsNameExpr()->Id();
auto id = f_rec->AsNameExpr()->IdPtr();
(*c)[id].push_back(s.get());
}
@ -1000,7 +995,7 @@ bool StmtList::ReduceStmt(unsigned int& s_i, std::vector<StmtPtr>& f_stmts, Redu
}
}
if ( c->IsTemporary(var->Id()) && ! c->IsParamTemp(var->Id()) && c->IsCSE(a, var, rhs.get()) ) {
if ( c->IsTemporary(var->IdPtr()) && ! c->IsParamTemp(var->IdPtr()) && c->IsCSE(a, var, rhs.get()) ) {
// printf("discarding %s as unnecessary\n", var->Id()->Name());
// Skip this now unnecessary statement.
return true;
@ -1106,7 +1101,7 @@ bool WhenInfo::HasUnreducedIDs(Reducer* c) const {
for ( auto& cp : *cl ) {
const auto& cid = cp.Id();
if ( ! when_new_locals.contains(cid.get()) && ! c->ID_IsReduced(cp.Id()) )
if ( when_new_locals.count(cid) == 0 && ! c->ID_IsReduced(cp.Id()) )
return true;
}
@ -1120,7 +1115,7 @@ bool WhenInfo::HasUnreducedIDs(Reducer* c) const {
void WhenInfo::UpdateIDs(Reducer* c) {
for ( auto& cp : *cl ) {
auto& cid = cp.Id();
if ( ! when_new_locals.contains(cid.get()) )
if ( when_new_locals.count(cid) == 0 )
cp.SetID(c->UpdateID(cid));
}

View file

@ -40,7 +40,7 @@ UsageAnalyzer::UsageAnalyzer(std::vector<FuncInfo>& funcs) {
auto& globals = global_scope()->Vars();
for ( auto& gpair : globals ) {
auto id = gpair.second.get();
auto& id = gpair.second;
auto& t = id->GetType();
if ( t->Tag() != TYPE_FUNC )
@ -69,7 +69,7 @@ UsageAnalyzer::UsageAnalyzer(std::vector<FuncInfo>& funcs) {
for ( auto& gpair : globals ) {
auto& id = gpair.second;
if ( reachables.contains(id.get()) )
if ( reachables.count(id) > 0 )
continue;
auto f = GetFuncIfAny(id);
@ -116,8 +116,10 @@ public:
return TC_CONTINUE;
}
TraversalCode PreID(const ID* id) override {
if ( ids.contains(id) )
TraversalCode PreID(const ID* raw_id) override {
IDPtr id{NewRef{}, const_cast<ID*>(raw_id)};
if ( ids.count(id) > 0 )
return TC_ABORTSTMT;
if ( attr_depth > 0 )
@ -132,7 +134,7 @@ public:
}
int attr_depth = 0; // Are we in an attribute?
std::set<const detail::ID*> ids; // List of IDs found in attributes.
std::unordered_set<IDPtr> ids; // List of IDs found in attributes.
std::set<const Type*> analyzed_types; // Endless recursion avoidance.
};
@ -142,15 +144,15 @@ void UsageAnalyzer::FindSeeds(IDSet& seeds) const {
auto& id = gpair.second;
if ( id->GetAttr(ATTR_IS_USED) || id->GetAttr(ATTR_DEPRECATED) ) {
seeds.insert(id.get());
seeds.insert(id);
continue;
}
auto f = GetFuncIfAny(id);
if ( f && id->GetType<FuncType>()->Flavor() == FUNC_FLAVOR_EVENT ) {
if ( ! script_events.contains(f->GetName()) )
seeds.insert(id.get());
if ( script_events.count(f->GetName()) == 0 )
seeds.insert(id);
continue;
}
@ -159,7 +161,7 @@ void UsageAnalyzer::FindSeeds(IDSet& seeds) const {
// it's meant to be used, even if the current scripts don't
// use it.
if ( id->IsExport() || id->ModuleName() == "GLOBAL" )
seeds.insert(id.get());
seeds.insert(id);
else
// ...otherwise, find all IDs referenced from attribute expressions
// found through this identifier.
@ -169,7 +171,7 @@ void UsageAnalyzer::FindSeeds(IDSet& seeds) const {
seeds.insert(attr_ids_collector.ids.begin(), attr_ids_collector.ids.end());
}
const Func* UsageAnalyzer::GetFuncIfAny(const ID* id) const {
const Func* UsageAnalyzer::GetFuncIfAny(const IDPtr& id) const {
auto& t = id->GetType();
if ( t->Tag() != TYPE_FUNC )
return nullptr;
@ -205,7 +207,7 @@ bool UsageAnalyzer::ExpandReachables(const IDSet& curr_r) {
return ! new_reachables.empty();
}
void UsageAnalyzer::Expand(const ID* id) {
void UsageAnalyzer::Expand(const IDPtr& id) {
// A subtle problem arises for exported globals that refer to functions
// that themselves generate events. Because for identifiers we don't
// traverse their values (since there's no Traverse infrastructure for
@ -224,8 +226,10 @@ void UsageAnalyzer::Expand(const ID* id) {
id->Traverse(this);
}
TraversalCode UsageAnalyzer::PreID(const ID* id) {
if ( analyzed_IDs.contains(id) )
TraversalCode UsageAnalyzer::PreID(const ID* raw_id) {
IDPtr id{NewRef{}, const_cast<ID*>(raw_id)};
if ( analyzed_IDs.count(id) > 0 )
// No need to repeat the analysis.
return TC_ABORTSTMT;

View file

@ -28,8 +28,7 @@ private:
// Given an identifier, return its corresponding script function,
// or nil if that's not applicable.
const Func* GetFuncIfAny(const ID* id) const;
const Func* GetFuncIfAny(const IDPtr& id) const { return GetFuncIfAny(id.get()); }
const Func* GetFuncIfAny(const IDPtr& id) const;
// Iteratively follows reachability across the set of reachable
// identifiers (starting with the seeds) until there's no more to reap.
@ -41,7 +40,7 @@ private:
// For a given identifier, populates new_reachables with new
// identifiers directly reachable from it.
void Expand(const ID* f);
void Expand(const IDPtr& f);
// Hooks into AST traversal to find reachable functions/hooks/events.
TraversalCode PreID(const ID* id) override;

View file

@ -74,7 +74,7 @@ bool UseDefs::RemoveUnused(int iter) {
std::vector<IDPtr> used_ids;
for ( const auto& id : inits )
if ( is_atomic_type(id->GetType()) || ! CheckIfUnused(s, id.get(), false) )
if ( is_atomic_type(id->GetType()) || ! CheckIfUnused(s, id, false) )
used_ids.emplace_back(id);
if ( used_ids.empty() ) { // There aren't any ID's to keep.
@ -118,7 +118,7 @@ bool UseDefs::RemoveUnused(int iter) {
if ( n->Tag() != EXPR_NAME )
reporter->InternalError("lhs name inconsistency in UseDefs::RemoveUnused");
auto id = n->AsNameExpr()->Id();
const auto& id = n->AsNameExpr()->IdPtr();
auto rhs = a->GetOp2();
auto rt = rhs->Tag();
@ -146,7 +146,7 @@ bool UseDefs::RemoveUnused(int iter) {
return did_omission;
}
bool UseDefs::CheckIfUnused(const Stmt* s, const ID* id, bool report) {
bool UseDefs::CheckIfUnused(const Stmt* s, const IDPtr& id, bool report) {
if ( id->IsGlobal() )
return false;
@ -247,7 +247,7 @@ UDs UseDefs::PropagateUDs(const Stmt* s, UDs succ_UDs, const Stmt* succ_stmt, bo
reporter->InternalError("lhs inconsistency in UseDefs::ExprUDs");
auto lhs_var = lhs_ref->GetOp1();
auto lhs_id = lhs_var->AsNameExpr()->Id();
auto lhs_id = lhs_var->AsNameExpr()->IdPtr();
auto lhs_UDs = RemoveID(lhs_id, succ_UDs);
auto rhs_UDs = ExprUDs(a->GetOp2().get());
auto uds = UD_Union(lhs_UDs, rhs_UDs);
@ -361,7 +361,7 @@ UDs UseDefs::PropagateUDs(const Stmt* s, UDs succ_UDs, const Stmt* succ_stmt, bo
auto val_var = f->ValueVar();
if ( val_var )
RemoveUDFrom(f_UDs, val_var.get());
RemoveUDFrom(f_UDs, val_var);
// The loop might not execute at all.
FoldInUDs(f_UDs, succ_UDs);
@ -540,7 +540,7 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e) {
switch ( e->Tag() ) {
case EXPR_REF: AddInExprUDs(uds, e->GetOp1().get()); break;
case EXPR_NAME: AddID(uds, e->AsNameExpr()->Id()); break;
case EXPR_NAME: AddID(uds, e->AsNameExpr()->IdPtr()); break;
case EXPR_LIST: {
auto l = e->AsListExpr();
@ -582,9 +582,9 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e) {
}
}
void UseDefs::AddID(UDs uds, const ID* id) const { uds->Add(id); }
void UseDefs::AddID(UDs uds, IDPtr id) const { uds->Add(std::move(id)); }
UDs UseDefs::RemoveID(const ID* id, const UDs& uds) {
UDs UseDefs::RemoveID(const IDPtr& id, const UDs& uds) {
if ( ! uds )
return nullptr;
@ -596,7 +596,7 @@ UDs UseDefs::RemoveID(const ID* id, const UDs& uds) {
return new_uds;
}
void UseDefs::RemoveUDFrom(UDs uds, const ID* id) {
void UseDefs::RemoveUDFrom(UDs uds, const IDPtr& id) {
if ( uds )
uds->Remove(id);
}

View file

@ -27,10 +27,10 @@ public:
void Replicate(const UDs& from) { use_defs = from->use_defs; }
bool HasID(const ID* id) { return use_defs.contains(id); }
bool HasID(const IDPtr& id) { return use_defs.find(id) != use_defs.end(); }
void Add(const ID* id) { use_defs.insert(id); }
void Remove(const ID* id) { use_defs.erase(id); }
void Add(IDPtr id) { use_defs.insert(std::move(id)); }
void Remove(const IDPtr& id) { use_defs.erase(id); }
const IDSet& IterateOver() const { return use_defs; }
@ -83,7 +83,7 @@ private:
// For a given identifier defined at a given statement, returns
// whether it is unused. If "report" is true, also reports
// this fact.
bool CheckIfUnused(const Stmt* s, const ID* id, bool report);
bool CheckIfUnused(const Stmt* s, const IDPtr& id, bool report);
// Propagates use-defs (backwards) across statement s,
// given its successor's UDs.
@ -112,14 +112,14 @@ private:
void AddInExprUDs(UDs uds, const Expr* e);
// Add an ID into an existing set of UDs.
void AddID(UDs uds, const ID* id) const;
void AddID(UDs uds, IDPtr id) const;
// Returns a new use-def corresponding to the given one, but
// with the definition of "id" removed.
UDs RemoveID(const ID* id, const UDs& uds);
UDs RemoveID(const IDPtr& id, const UDs& uds);
// Similar, but updates the UDs in place.
void RemoveUDFrom(UDs uds, const ID* id);
void RemoveUDFrom(UDs uds, const IDPtr& id);
// Adds in the additional UDs to the main UDs. Always creates
// a new use_def and updates main_UDs to point to it.

View file

@ -431,7 +431,7 @@ void ZAMCompiler::ComputeFrameLifetimes() {
case OP_STORE_GLOBAL_g: {
// Use of the global goes to here.
auto slot = frame_layout1[globalsI[inst->v1].id.get()];
const auto& slot = frame_layout1[globalsI[inst->v1].id];
ExtendLifetime(slot, EndOfLoop(inst, 1));
break;
}
@ -671,7 +671,7 @@ void ZAMCompiler::ReMapInterpreterFrame() {
remapped_intrp_frame_sizes[f] = next_interp_slot;
}
void ZAMCompiler::ReMapVar(const ID* id, int slot, zeek_uint_t inst) {
void ZAMCompiler::ReMapVar(const IDPtr& id, int slot, zeek_uint_t inst) {
// A greedy algorithm for this is to simply find the first suitable
// frame slot. We do that with one twist: we also look for a
// compatible slot for which its current end-of-scope is exactly

View file

@ -38,7 +38,7 @@ void ReMapInterpreterFrame();
// Computes the remapping for a variable currently in the given slot,
// whose scope begins at the given instruction.
void ReMapVar(const ID* id, int slot, zeek_uint_t inst);
void ReMapVar(const IDPtr& id, int slot, zeek_uint_t inst);
// Look to initialize the beginning of local lifetime based on slot
// assignment at instruction inst.

View file

@ -156,7 +156,7 @@ private:
std::shared_ptr<Reducer> reducer;
// Maps identifiers to their (unique) frame location.
std::unordered_map<const ID*, int> frame_layout1;
std::unordered_map<IDPtr, int> frame_layout1;
// Inverse mapping, used for tracking frame usage (and for dumping
// statements).
@ -201,7 +201,7 @@ private:
// values that get finalized when constructing the corresponding
// ZBody.
std::vector<GlobalInfo> globalsI;
std::unordered_map<const ID*, int> global_id_to_info; // inverse
std::unordered_map<IDPtr, int> global_id_to_info; // inverse
// Intermediary switch tables (branching to ZInst's rather
// than concrete instruction offsets).

View file

@ -47,13 +47,11 @@ void ZAMCompiler::Init() {
}
void ZAMCompiler::InitGlobals() {
for ( auto g : pf->Globals() ) {
auto non_const_g = const_cast<ID*>(g);
for ( auto& g : pf->Globals() ) {
GlobalInfo info;
info.id = {NewRef{}, non_const_g};
info.slot = AddToFrame(non_const_g);
global_id_to_info[non_const_g] = globalsI.size();
info.id = g;
info.slot = AddToFrame(g);
global_id_to_info[g] = globalsI.size();
globalsI.push_back(info);
}
}
@ -70,9 +68,8 @@ void ZAMCompiler::InitArgs() {
if ( --nparam < 0 )
break;
auto arg_id = a.get();
if ( uds && uds->HasID(arg_id) )
LoadParam(arg_id);
if ( uds && uds->HasID(a) )
LoadParam(a);
else {
// printf("param %s unused\n", obj_desc(arg_id.get()));
}
@ -88,22 +85,20 @@ void ZAMCompiler::InitCaptures() {
void ZAMCompiler::InitLocals() {
// Assign slots for locals (which includes temporaries).
for ( auto l : pf->Locals() ) {
for ( auto& l : pf->Locals() ) {
if ( IsCapture(l) )
continue;
if ( pf->WhenLocals().contains(l) )
continue;
auto non_const_l = const_cast<ID*>(l);
// Don't add locals that were already added because they're
// parameters.
//
// Don't worry about unused variables, those will get
// removed during low-level ZAM optimization.
if ( ! HasFrameSlot(non_const_l) )
(void)AddToFrame(non_const_l);
if ( ! HasFrameSlot(l) )
(void)AddToFrame(l);
}
}

View file

@ -951,7 +951,7 @@ const ZAMStmt ZAMCompiler::BuildLambda(int n_slot, ExprPtr e) {
for ( int i = 0; i < ncaptures; ++i ) {
auto& id_i = (*captures)[i].Id();
if ( pf->WhenLocals().contains(id_i.get()) )
if ( pf->WhenLocals().count(id_i) > 0 )
aux->Add(i, nullptr);
else
aux->Add(i, FrameSlot(id_i), id_i->GetType());

View file

@ -16,7 +16,7 @@ using AttributesPtr = IntrusivePtr<Attributes>;
// Maps ZAM frame slots to associated identifiers. These are the simplest
// types of frames, where each identifier has its own slot.
using FrameMap = std::vector<const ID*>;
using FrameMap = std::vector<IDPtr>;
// Maps ZAM frame slots to information for sharing the slot across
// multiple script variables.
@ -25,7 +25,7 @@ public:
// The variables sharing the slot. ID's need to be non-const so we
// can manipulate them, for example by changing their interpreter
// frame offset.
std::vector<const ID*> ids;
std::vector<IDPtr> ids;
// A parallel vector, only used for fully compiled code, which
// gives the names of the identifiers. When in use, the above

View file

@ -163,7 +163,7 @@ const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst, bool suppress_non_local)
else
op = OP_STORE_CAPTURE_Vi;
auto store_inst = ZInstI(op, RawSlot(c_id.get()), cs);
auto store_inst = ZInstI(op, RawSlot(c_id), cs);
store_inst.op_type = OP_VV_I2;
return AddInst(store_inst);

View file

@ -702,13 +702,11 @@ const ZAMStmt ZAMCompiler::LoopOverTable(const ForStmt* f, const NameExpr* val)
// variables are actually used in the body. Now that we have '_'
// loop placeholder variables, this is no longer worth trying to
// optimize for, though we still optimize for those placeholders.
int num_unused = 0;
size_t num_unused = 0;
auto aux = new ZInstAux(0);
for ( auto i = 0; i < loop_vars->length(); ++i ) {
auto id = (*loop_vars)[i];
for ( const auto& id : *loop_vars ) {
if ( id->IsBlank() )
++num_unused;
@ -719,7 +717,7 @@ const ZAMStmt ZAMCompiler::LoopOverTable(const ForStmt* f, const NameExpr* val)
aux->is_managed.push_back(ZVal::IsManagedType(t));
}
bool no_loop_vars = (num_unused == loop_vars->length());
bool no_loop_vars = (num_unused == loop_vars->size());
if ( value_var )
aux->value_var_type = value_var->GetType();

View file

@ -17,21 +17,21 @@ bool ZAMCompiler::IsUnused(const IDPtr& id, const Stmt* where) const {
// "usage" can be nil if due to constant propagation we've prune
// all of the uses of the given identifier.
return ! usage || ! usage->HasID(id.get());
return ! usage || ! usage->HasID(id);
}
bool ZAMCompiler::IsCapture(const ID* id) const {
bool ZAMCompiler::IsCapture(const IDPtr& id) const {
const auto& c = pf->CapturesOffsets();
return c.contains(id);
}
int ZAMCompiler::CaptureOffset(const ID* id) const {
int ZAMCompiler::CaptureOffset(const IDPtr& id) const {
auto id_offset = pf->CapturesOffsets().find(id);
ASSERT(id_offset != pf->CapturesOffsets().end());
return id_offset->second;
}
void ZAMCompiler::LoadParam(const ID* id) {
void ZAMCompiler::LoadParam(const IDPtr& id) {
if ( id->IsType() )
reporter->InternalError("don't know how to compile local variable that's a type not a value");
@ -50,7 +50,7 @@ void ZAMCompiler::LoadParam(const ID* id) {
(void)AddInst(z);
}
const ZAMStmt ZAMCompiler::LoadGlobal(const ID* id) {
const ZAMStmt ZAMCompiler::LoadGlobal(const IDPtr& id) {
ZOp op;
if ( id->IsType() )
@ -68,12 +68,12 @@ const ZAMStmt ZAMCompiler::LoadGlobal(const ID* id) {
// We use the id_val for reporting used-but-not-set errors.
z.aux = new ZInstAux(0);
z.aux->id_val = {NewRef{}, const_cast<ID*>(id)};
z.aux->id_val = std::move(id);
return AddInst(z, true);
}
const ZAMStmt ZAMCompiler::LoadCapture(const ID* id) {
const ZAMStmt ZAMCompiler::LoadCapture(const IDPtr& id) {
ZOp op;
if ( ZVal::IsManagedType(id->GetType()) )
@ -90,13 +90,13 @@ const ZAMStmt ZAMCompiler::LoadCapture(const ID* id) {
return AddInst(z, true);
}
int ZAMCompiler::AddToFrame(const ID* id) {
int ZAMCompiler::AddToFrame(const IDPtr& id) {
frame_layout1[id] = frame_sizeI;
frame_denizens.push_back(id);
return frame_sizeI++;
}
int ZAMCompiler::FrameSlot(const ID* id) {
int ZAMCompiler::FrameSlot(const IDPtr& id) {
auto slot = RawSlot(id);
if ( id->IsGlobal() )
@ -108,7 +108,7 @@ int ZAMCompiler::FrameSlot(const ID* id) {
return slot;
}
int ZAMCompiler::Frame1Slot(const ID* id, ZAMOp1Flavor fl) {
int ZAMCompiler::Frame1Slot(const IDPtr& id, ZAMOp1Flavor fl) {
if ( fl == OP1_READ )
return FrameSlot(id);
@ -134,7 +134,7 @@ int ZAMCompiler::Frame1Slot(const ID* id, ZAMOp1Flavor fl) {
return slot;
}
int ZAMCompiler::RawSlot(const ID* id) {
int ZAMCompiler::RawSlot(const IDPtr& id) {
auto id_slot = frame_layout1.find(id);
if ( id_slot == frame_layout1.end() )
@ -143,7 +143,7 @@ int ZAMCompiler::RawSlot(const ID* id) {
return id_slot->second;
}
bool ZAMCompiler::HasFrameSlot(const ID* id) const { return frame_layout1.contains(id); }
bool ZAMCompiler::HasFrameSlot(const IDPtr& id) const { return frame_layout1.contains(id); }
int ZAMCompiler::NewSlot(bool is_managed) {
char buf[8192];
@ -154,7 +154,7 @@ int ZAMCompiler::NewSlot(bool is_managed) {
auto tag = is_managed ? TYPE_TABLE : TYPE_VOID;
auto internal_reg = new ID(buf, SCOPE_FUNCTION, false);
auto internal_reg = make_intrusive<ID>(buf, SCOPE_FUNCTION, false);
internal_reg->SetType(base_type(tag));
return AddToFrame(internal_reg);

View file

@ -6,37 +6,33 @@
bool IsUnused(const IDPtr& id, const Stmt* where) const;
bool IsCapture(const IDPtr& id) const { return IsCapture(id.get()); }
bool IsCapture(const ID* id) const;
bool IsCapture(const IDPtr& id) const;
int CaptureOffset(const IDPtr& id) const;
int CaptureOffset(const IDPtr& id) const { return IsCapture(id.get()); }
int CaptureOffset(const ID* id) const;
void LoadParam(const IDPtr& id);
const ZAMStmt LoadGlobal(const IDPtr& id);
const ZAMStmt LoadCapture(const IDPtr& id);
void LoadParam(const ID* id);
const ZAMStmt LoadGlobal(const ID* id);
const ZAMStmt LoadCapture(const ID* id);
int AddToFrame(const IDPtr&);
int AddToFrame(const ID*);
int FrameSlot(const IDPtr& id) { return FrameSlot(id.get()); }
int FrameSlot(const ID* id);
int FrameSlot(const IDPtr& id);
int FrameSlotIfName(const Expr* e) {
auto n = e->Tag() == EXPR_NAME ? e->AsNameExpr() : nullptr;
return n ? FrameSlot(n->Id()) : -1;
return n ? FrameSlot(n->IdPtr()) : -1;
}
int FrameSlot(const NameExpr* n) { return FrameSlot(n->Id()); }
int Frame1Slot(const NameExpr* n, ZOp op) { return Frame1Slot(n->Id(), op); }
int FrameSlot(const NameExpr* n) { return FrameSlot(n->IdPtr()); }
int Frame1Slot(const NameExpr* n, ZOp op) { return Frame1Slot(n->IdPtr(), op); }
int Frame1Slot(const ID* id, ZOp op) { return Frame1Slot(id, op1_flavor[op]); }
int Frame1Slot(const NameExpr* n, ZAMOp1Flavor fl) { return Frame1Slot(n->Id(), fl); }
int Frame1Slot(const ID* id, ZAMOp1Flavor fl);
int Frame1Slot(const IDPtr& id, ZOp op) { return Frame1Slot(id, op1_flavor[op]); }
int Frame1Slot(const NameExpr* n, ZAMOp1Flavor fl) { return Frame1Slot(n->IdPtr(), fl); }
int Frame1Slot(const IDPtr& id, ZAMOp1Flavor fl);
// The slot without doing any global-related checking.
int RawSlot(const NameExpr* n) { return RawSlot(n->Id()); }
int RawSlot(const ID* id);
int RawSlot(const NameExpr* n) { return RawSlot(n->IdPtr()); }
int RawSlot(const IDPtr& id);
bool HasFrameSlot(const ID* id) const;
bool HasFrameSlot(const IDPtr& id) const;
int NewSlot(const TypePtr& t) { return NewSlot(ZVal::IsManagedType(t)); }
int NewSlot(bool is_managed);

View file

@ -398,7 +398,7 @@ string ZInstI::VName(int n, const FrameMap* frame_ids, const FrameReMap* remappi
if ( slot < 0 )
return "<special>";
const ID* id;
IDPtr id;
if ( remappings && live ) { // Find which identifier manifests at this instruction.
ASSERT(slot >= 0 && static_cast<zeek_uint_t>(slot) < remappings->size());