Switch parsing to use vector<IntrusivePtr<Attr>> from attr_list

This allows improved passing/storing of Attr references to Exprs,
TypeDecl, Scope, etc.
This commit is contained in:
Jon Siwek 2020-05-26 18:19:29 -07:00
parent ce6f69cd19
commit 8b6de5852c
10 changed files with 194 additions and 239 deletions

View file

@ -2002,7 +2002,7 @@ void RefExpr::Assign(Frame* f, IntrusivePtr<Val> v)
AssignExpr::AssignExpr(IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2,
bool arg_is_init, IntrusivePtr<Val> arg_val,
attr_list* arg_attrs)
const IntrusivePtr<Attributes>& attrs)
: BinaryExpr(EXPR_ASSIGN, arg_is_init ?
std::move(arg_op1) : arg_op1->MakeLvalue(),
std::move(arg_op2))
@ -2027,14 +2027,14 @@ AssignExpr::AssignExpr(IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2,
// We discard the status from TypeCheck since it has already
// generated error messages.
(void) TypeCheck(arg_attrs);
(void) TypeCheck(attrs);
val = std::move(arg_val);
SetLocationInfo(op1->GetLocationInfo(), op2->GetLocationInfo());
}
bool AssignExpr::TypeCheck(attr_list* attrs)
bool AssignExpr::TypeCheck(const IntrusivePtr<Attributes>& attrs)
{
TypeTag bt1 = op1->GetType()->Tag();
TypeTag bt2 = op2->GetType()->Tag();
@ -2069,22 +2069,19 @@ bool AssignExpr::TypeCheck(attr_list* attrs)
if ( bt1 == TYPE_TABLE && op2->Tag() == EXPR_LIST )
{
attr_list* attr_copy = nullptr;
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr_copy;
if ( attrs )
{
attr_copy = new attr_list(attrs->length());
std::copy(attrs->begin(), attrs->end(), std::back_inserter(*attr_copy));
}
attr_copy = std::make_unique<std::vector<IntrusivePtr<Attr>>>(attrs->Attrs());
bool empty_list_assignment = (op2->AsListExpr()->Exprs().empty());
if ( op1->GetType()->IsSet() )
op2 = make_intrusive<SetConstructorExpr>(
IntrusivePtr{NewRef{}, op2->AsListExpr()}, attr_copy);
cast_intrusive<ListExpr>(op2), std::move(attr_copy));
else
op2 = make_intrusive<TableConstructorExpr>(
IntrusivePtr{NewRef{}, op2->AsListExpr()}, attr_copy);
cast_intrusive<ListExpr>(op2), std::move(attr_copy));
if ( ! empty_list_assignment && ! same_type(op1->GetType(), op2->GetType()) )
{
@ -2166,23 +2163,19 @@ bool AssignExpr::TypeCheck(attr_list* attrs)
return false;
}
attr_list* attr_copy = nullptr;
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr_copy;
if ( sce->Attrs() )
if ( sce->GetAttrs() )
{
const auto& a = sce->Attrs()->Attrs();
attr_copy = new attr_list(a.size());
for ( const auto& attr : a )
{
::Ref(attr.get());
attrs->push_back(attr.get());
}
const auto& a = sce->GetAttrs()->Attrs();
attr_copy = std::make_unique<std::vector<IntrusivePtr<Attr>>>(a);
}
int errors_before = reporter->Errors();
op2 = make_intrusive<SetConstructorExpr>(
IntrusivePtr{NewRef{}, ctor_list}, attr_copy,
IntrusivePtr{NewRef{}, ctor_list},
std::move(attr_copy),
op1->GetType());
int errors_after = reporter->Errors();
@ -2286,7 +2279,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const
if ( IsError() )
return;
TypeDecl td(nullptr, nullptr);
TypeDecl td;
if ( IsRecordElement(&td) )
{
@ -2341,7 +2334,7 @@ IntrusivePtr<Val> AssignExpr::InitVal(const BroType* t, IntrusivePtr<Val> aggr)
if ( IsError() )
return nullptr;
TypeDecl td(nullptr, nullptr);
TypeDecl td;
if ( IsRecordElement(&td) )
{
@ -2997,7 +2990,7 @@ RecordConstructorExpr::RecordConstructorExpr(IntrusivePtr<ListExpr> constructor_
FieldAssignExpr* field = (FieldAssignExpr*) e;
const auto& field_type = field->GetType();
char* field_name = copy_string(field->FieldName());
record_types->push_back(new TypeDecl(field_type, field_name));
record_types->push_back(new TypeDecl(field_name, field_type));
}
SetType(make_intrusive<RecordType>(record_types));
@ -3051,10 +3044,9 @@ void RecordConstructorExpr::ExprDescribe(ODesc* d) const
}
TableConstructorExpr::TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
attr_list* arg_attrs,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> arg_attrs,
IntrusivePtr<BroType> arg_type)
: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, std::move(constructor_list)),
attrs(nullptr)
: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, std::move(constructor_list))
{
if ( IsError() )
return;
@ -3088,15 +3080,7 @@ TableConstructorExpr::TableConstructorExpr(IntrusivePtr<ListExpr> constructor_li
}
if ( arg_attrs )
{
std::vector<IntrusivePtr<Attr>> attrv;
for ( auto& a : *arg_attrs )
attrv.emplace_back(AdoptRef{}, a);
attrs = new Attributes(std::move(attrv), type, false, false);
delete arg_attrs;
}
attrs = make_intrusive<Attributes>(std::move(*arg_attrs), type, false, false);
const auto& indices = type->AsTableType()->GetIndices()->Types();
const expr_list& cle = op->AsListExpr()->Exprs();
@ -3144,8 +3128,7 @@ IntrusivePtr<Val> TableConstructorExpr::Eval(Frame* f) const
if ( IsError() )
return nullptr;
auto aggr = make_intrusive<TableVal>(GetType<TableType>(),
IntrusivePtr{NewRef{}, attrs});
auto aggr = make_intrusive<TableVal>(GetType<TableType>(), attrs);
const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& expr : exprs )
@ -3165,7 +3148,7 @@ IntrusivePtr<Val> TableConstructorExpr::InitVal(const BroType* t, IntrusivePtr<V
auto tval = aggr ?
IntrusivePtr<TableVal>{AdoptRef{}, aggr.release()->AsTableVal()} :
make_intrusive<TableVal>(std::move(tt), IntrusivePtr{NewRef{}, attrs});
make_intrusive<TableVal>(std::move(tt), attrs);
const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& expr : exprs )
@ -3182,10 +3165,9 @@ void TableConstructorExpr::ExprDescribe(ODesc* d) const
}
SetConstructorExpr::SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
attr_list* arg_attrs,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> arg_attrs,
IntrusivePtr<BroType> arg_type)
: UnaryExpr(EXPR_SET_CONSTRUCTOR, std::move(constructor_list)),
attrs(nullptr)
: UnaryExpr(EXPR_SET_CONSTRUCTOR, std::move(constructor_list))
{
if ( IsError() )
return;
@ -3216,15 +3198,7 @@ SetConstructorExpr::SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
SetError("values in set(...) constructor do not specify a set");
if ( arg_attrs )
{
std::vector<IntrusivePtr<Attr>> attrv;
for ( auto& a : *arg_attrs )
attrv.emplace_back(AdoptRef{}, a);
attrs = new Attributes(std::move(attrv), type, false, false);
delete arg_attrs;
}
attrs = make_intrusive<Attributes>(std::move(*arg_attrs), type, false, false);
const auto& indices = type->AsTableType()->GetIndices()->Types();
expr_list& cle = op->AsListExpr()->Exprs();
@ -3264,7 +3238,7 @@ IntrusivePtr<Val> SetConstructorExpr::Eval(Frame* f) const
return nullptr;
auto aggr = make_intrusive<TableVal>(IntrusivePtr{NewRef{}, type->AsTableType()},
IntrusivePtr{NewRef{}, attrs});
attrs);
const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& expr : exprs )
@ -3285,7 +3259,7 @@ IntrusivePtr<Val> SetConstructorExpr::InitVal(const BroType* t, IntrusivePtr<Val
auto tt = GetType<TableType>();
auto tval = aggr ?
IntrusivePtr<TableVal>{AdoptRef{}, aggr.release()->AsTableVal()} :
make_intrusive<TableVal>(std::move(tt), IntrusivePtr{NewRef{}, attrs});
make_intrusive<TableVal>(std::move(tt), attrs);
const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& e : exprs )

View file

@ -519,7 +519,8 @@ public:
// If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers.
AssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, bool is_init,
IntrusivePtr<Val> val = nullptr, attr_list* attrs = nullptr);
IntrusivePtr<Val> val = nullptr,
const IntrusivePtr<Attributes>& attrs = nullptr);
IntrusivePtr<Val> Eval(Frame* f) const override;
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
@ -529,7 +530,7 @@ public:
bool IsPure() const override;
protected:
bool TypeCheck(attr_list* attrs = nullptr);
bool TypeCheck(const IntrusivePtr<Attributes>& attrs = nullptr);
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
bool is_init;
@ -630,11 +631,15 @@ protected:
class TableConstructorExpr final : public UnaryExpr {
public:
TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs,
IntrusivePtr<BroType> arg_type = nullptr);
~TableConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
[[deprecated("Remove in v4.1. Use GetAttrs().")]]
Attributes* Attrs() { return attrs.get(); }
const IntrusivePtr<Attributes>& GetAttrs() const
{ return attrs; }
IntrusivePtr<Val> Eval(Frame* f) const override;
@ -643,16 +648,20 @@ protected:
void ExprDescribe(ODesc* d) const override;
Attributes* attrs;
IntrusivePtr<Attributes> attrs;
};
class SetConstructorExpr final : public UnaryExpr {
public:
SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs,
IntrusivePtr<BroType> arg_type = nullptr);
~SetConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
[[deprecated("Remove in v4.1. Use GetAttrs().")]]
Attributes* Attrs() { return attrs.get(); }
const IntrusivePtr<Attributes>& GetAttrs() const
{ return attrs; }
IntrusivePtr<Val> Eval(Frame* f) const override;
@ -661,7 +670,7 @@ protected:
void ExprDescribe(ODesc* d) const override;
Attributes* attrs;
IntrusivePtr<Attributes> attrs;
};
class VectorConstructorExpr final : public UnaryExpr {

View file

@ -840,7 +840,7 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
// Gets a function's priority from its Scope's attributes. Errors if it sees any
// problems.
static int get_func_priority(const attr_list& attrs)
static int get_func_priority(const std::vector<IntrusivePtr<Attr>>& attrs)
{
int priority = 0;
@ -883,7 +883,7 @@ function_ingredients::function_ingredients(IntrusivePtr<Scope> scope, IntrusiveP
this->scope = std::move(scope);
id = {NewRef{}, this->scope->ScopeID()};
auto attrs = this->scope->Attrs();
const auto& attrs = this->scope->Attrs();
priority = (attrs ? get_func_priority(*attrs) : 0);
this->body = std::move(body);

View file

@ -15,10 +15,10 @@ typedef PList<Scope> scope_list;
static scope_list scopes;
static Scope* top_scope;
Scope::Scope(IntrusivePtr<ID> id, attr_list* al)
: scope_id(std::move(id))
Scope::Scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> al)
: scope_id(std::move(id)), attrs(std::move(al))
{
attrs = al;
return_type = nullptr;
inits = new id_list;
@ -39,14 +39,6 @@ Scope::Scope(IntrusivePtr<ID> id, attr_list* al)
Scope::~Scope()
{
if ( attrs )
{
for ( const auto& attr : *attrs )
Unref(attr);
delete attrs;
}
if ( inits )
{
for ( const auto& i : *inits )
@ -210,9 +202,10 @@ void push_existing_scope(Scope* scope)
scopes.push_back(scope);
}
void push_scope(IntrusivePtr<ID> id, attr_list* attrs)
void push_scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs)
{
top_scope = new Scope(std::move(id), attrs);
top_scope = new Scope(std::move(id), std::move(attrs));
scopes.push_back(top_scope);
}

View file

@ -19,7 +19,8 @@ class ListVal;
class Scope : public BroObj {
public:
explicit Scope(IntrusivePtr<ID> id, attr_list* al);
explicit Scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> al);
~Scope() override;
const IntrusivePtr<ID>& Find(std::string_view name) const;
@ -35,7 +36,10 @@ public:
IntrusivePtr<ID> Remove(std::string_view name);
ID* ScopeID() const { return scope_id.get(); }
attr_list* Attrs() const { return attrs; }
const std::unique_ptr<std::vector<IntrusivePtr<Attr>>>& Attrs() const
{ return attrs; }
BroType* ReturnType() const { return return_type.get(); }
size_t Length() const { return local.size(); }
@ -56,7 +60,7 @@ public:
protected:
IntrusivePtr<ID> scope_id;
attr_list* attrs;
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs;
IntrusivePtr<BroType> return_type;
std::map<std::string, IntrusivePtr<ID>, std::less<>> local;
id_list* inits;
@ -74,7 +78,8 @@ extern const IntrusivePtr<ID>& lookup_ID(const char* name, const char* module,
extern IntrusivePtr<ID> install_ID(const char* name, const char* module_name,
bool is_global, bool is_export);
extern void push_scope(IntrusivePtr<ID> id, attr_list* attrs);
extern void push_scope(IntrusivePtr<ID> id,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs);
extern void push_existing_scope(Scope* scope);
// Returns the one popped off.

View file

@ -607,21 +607,12 @@ std::optional<FuncType::Prototype> FuncType::FindPrototype(const RecordType& arg
return {};
}
TypeDecl::TypeDecl(IntrusivePtr<BroType> t, const char* i, attr_list* arg_attrs, bool in_record)
TypeDecl::TypeDecl(const char* i, IntrusivePtr<BroType> t,
IntrusivePtr<Attributes> arg_attrs)
: type(std::move(t)),
attrs(std::move(arg_attrs)),
id(i)
{
if ( arg_attrs )
{
std::vector<IntrusivePtr<Attr>> attrv;
for ( auto& a : *arg_attrs )
attrv.emplace_back(AdoptRef{}, a);
attrs = make_intrusive<Attributes>(std::move(attrv), type, in_record, false);
delete arg_attrs;
}
}
{}
TypeDecl::TypeDecl(const TypeDecl& other)
{
@ -832,35 +823,24 @@ IntrusivePtr<TableVal> RecordType::GetRecordFieldsVal(const RecordVal* rv) const
return rval;
}
const char* RecordType::AddFields(type_decl_list* others, attr_list* attr)
const char* RecordType::AddFields(const type_decl_list& others,
bool add_log_attr)
{
assert(types);
bool log = false;
if ( attr )
{
for ( const auto& at : *attr )
{
if ( at->Tag() == ATTR_LOG )
log = true;
}
}
for ( const auto& td : *others )
for ( const auto& td : others )
{
if ( ! td->GetAttr(ATTR_DEFAULT) && ! td->GetAttr(ATTR_OPTIONAL) )
{
delete others;
return "extension field must be &optional or have &default";
}
}
TableVal::SaveParseTimeTableState(this);
for ( const auto& td : *others )
for ( const auto& td : others )
{
if ( log )
if ( add_log_attr )
{
if ( ! td->attrs )
td->attrs = make_intrusive<Attributes>(td->type, true, false);
@ -871,8 +851,6 @@ const char* RecordType::AddFields(type_decl_list* others, attr_list* attr)
types->push_back(td);
}
delete others;
num_fields = types->length();
RecordVal::ResizeParseTimeRecords(this);
TableVal::RebuildParseTimeTables();
@ -1878,7 +1856,7 @@ IntrusivePtr<BroType> merge_types(const IntrusivePtr<BroType>& arg_t1,
return nullptr;
}
tdl3->push_back(new TypeDecl(std::move(tdl3_i), copy_string(td1->id)));
tdl3->push_back(new TypeDecl(copy_string(td1->id), std::move(tdl3_i)));
}
return make_intrusive<RecordType>(tdl3);

View file

@ -562,7 +562,8 @@ protected:
class TypeDecl final {
public:
TypeDecl(IntrusivePtr<BroType> t, const char* i, attr_list* attrs = nullptr, bool in_record = false);
TypeDecl() = default;
TypeDecl(const char* i, IntrusivePtr<BroType> t, IntrusivePtr<Attributes> attrs = nullptr);
TypeDecl(const TypeDecl& other);
~TypeDecl();
@ -577,7 +578,7 @@ public:
IntrusivePtr<BroType> type;
IntrusivePtr<Attributes> attrs;
const char* id;
const char* id = nullptr;
};
typedef PList<TypeDecl> type_decl_list;
@ -656,9 +657,9 @@ public:
*/
IntrusivePtr<TableVal> GetRecordFieldsVal(const RecordVal* rv = nullptr) const;
// Returns 0 if all is ok, otherwise a pointer to an error message.
// Takes ownership of list.
const char* AddFields(type_decl_list* types, attr_list* attr);
// Returns null if all is ok, otherwise a pointer to an error message.
const char* AddFields(const type_decl_list& types,
bool add_log_attr = false);
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool roles_only = false) const override;

View file

@ -30,7 +30,8 @@ static IntrusivePtr<Val> init_val(Expr* init, const BroType* t,
}
}
static bool add_prototype(ID* id, BroType* t, attr_list* attrs,
static bool add_prototype(ID* id, BroType* t,
std::vector<IntrusivePtr<Attr>>* attrs,
const IntrusivePtr<Expr>& init)
{
if ( ! IsFunc(id->GetType()->Tag()) )
@ -108,7 +109,9 @@ static bool add_prototype(ID* id, BroType* t, attr_list* attrs,
}
static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt,
bool do_init)
{
if ( id->GetType() )
@ -123,7 +126,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
else if ( dt != VAR_REDEF || init || ! attr )
{
if ( IsFunc(id->GetType()->Tag()) )
add_prototype(id, t.get(), attr, init);
add_prototype(id, t.get(), attr.get(), init);
else
id->Error("already defined", init.get());
@ -196,14 +199,7 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
id->SetType(t);
if ( attr )
{
std::vector<IntrusivePtr<Attr>> attrv;
for ( auto& a : *attr)
attrv.emplace_back(AdoptRef{}, a);
id->AddAttrs(make_intrusive<Attributes>(std::move(attrv), t, false, id->IsGlobal()));
}
id->AddAttrs(make_intrusive<Attributes>(std::move(*attr), t, false, id->IsGlobal()));
if ( init )
{
@ -211,16 +207,16 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
case EXPR_TABLE_CONSTRUCTOR:
{
TableConstructorExpr* ctor = (TableConstructorExpr*) init.get();
if ( ctor->Attrs() )
id->AddAttrs({NewRef{}, ctor->Attrs()});
if ( ctor->GetAttrs() )
id->AddAttrs(ctor->GetAttrs());
}
break;
case EXPR_SET_CONSTRUCTOR:
{
SetConstructorExpr* ctor = (SetConstructorExpr*) init.get();
if ( ctor->Attrs() )
id->AddAttrs({NewRef{}, ctor->Attrs()});
if ( ctor->GetAttrs() )
id->AddAttrs(ctor->GetAttrs());
}
break;
@ -312,16 +308,19 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
void add_global(ID* id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt)
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt)
{
make_var(id, std::move(t), c, std::move(init), attr, dt, true);
make_var(id, std::move(t), c, std::move(init), std::move(attr), dt, true);
}
IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
init_class c, IntrusivePtr<Expr> init,
attr_list* attr, decl_type dt)
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt)
{
make_var(id.get(), std::move(t), c, init, attr, dt, false);
make_var(id.get(), std::move(t), c, init, std::move(attr), dt, false);
if ( init )
{
@ -333,20 +332,9 @@ IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
*init->GetLocationInfo() : no_location;
auto name_expr = make_intrusive<NameExpr>(id, dt == VAR_CONST);
attr_list* attrs = nullptr;
if ( id->GetAttrs() )
{
attrs = new attr_list(id->GetAttrs()->Attrs().size());
for ( const auto& a : id->GetAttrs()->Attrs() )
attrs->push_back(a.get());
}
auto assign_expr = make_intrusive<AssignExpr>(std::move(name_expr),
std::move(init), 0,
nullptr, attrs);
delete attrs;
nullptr, id->GetAttrs());
auto stmt = make_intrusive<ExprStmt>(std::move(assign_expr));
stmt->SetLocationInfo(&location);
return stmt;
@ -369,7 +357,8 @@ extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
false, std::move(val));
}
void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
void add_type(ID* id, IntrusivePtr<BroType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr)
{
std::string new_type_name = id->Name();
std::string old_type_name = t->GetName();
@ -394,15 +383,7 @@ void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
id->MakeType();
if ( attr )
{
std::vector<IntrusivePtr<Attr>> attrv;
for ( auto& a : *attr )
attrv.emplace_back(AdoptRef{}, a);
id->SetAttrs(make_intrusive<Attributes>(std::move(attrv), tnew, false, false));
delete attr;
}
id->SetAttrs(make_intrusive<Attributes>(std::move(*attr), tnew, false, false));
}
static void transfer_arg_defaults(RecordType* args, RecordType* recv)
@ -430,23 +411,18 @@ static void transfer_arg_defaults(RecordType* args, RecordType* recv)
}
}
static Attr* find_attr(const attr_list* al, attr_tag tag)
static Attr* find_attr(const std::vector<IntrusivePtr<Attr>>* al, attr_tag tag)
{
if ( ! al )
return nullptr;
for ( int i = 0; i < al->length(); ++i )
for ( size_t i = 0; i < al->size(); ++i )
if ( (*al)[i]->Tag() == tag )
return (*al)[i];
return (*al)[i].get();
return nullptr;
}
static bool has_attr(const attr_list* al, attr_tag tag)
{
return find_attr(al, tag) != nullptr;
}
static std::optional<FuncType::Prototype> func_type_check(const FuncType* decl, const FuncType* impl)
{
if ( decl->Flavor() != impl->Flavor() )
@ -483,7 +459,8 @@ static bool canonical_arg_types_match(const FuncType* decl, const FuncType* impl
}
void begin_func(ID* id, const char* module_name, function_flavor flavor,
bool is_redef, IntrusivePtr<FuncType> t, attr_list* attrs)
bool is_redef, IntrusivePtr<FuncType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs)
{
if ( flavor == FUNC_FLAVOR_EVENT )
{
@ -580,7 +557,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
else
id->SetType(t);
push_scope({NewRef{}, id}, attrs);
push_scope({NewRef{}, id}, std::move(attrs));
const auto& args = t->Params();
int num_args = args->NumFields();
@ -600,7 +577,8 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
arg_id->SetOffset(prototype->offsets[i]);
}
if ( Attr* depr_attr = find_attr(attrs, ATTR_DEPRECATED) )
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(),
ATTR_DEPRECATED) )
id->MakeDeprecated(depr_attr->GetExpr());
}

View file

@ -17,23 +17,30 @@ class ListVal;
typedef enum { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, } decl_type;
extern void add_global(ID* id, IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt);
extern void add_global(ID* id,
IntrusivePtr<BroType> t,
init_class c,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt);
extern IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id,
IntrusivePtr<BroType> t, init_class c,
IntrusivePtr<Expr> init, attr_list* attr,
IntrusivePtr<BroType> t,
init_class c,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt);
extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
IntrusivePtr<Expr> init,
IntrusivePtr<Val> val = nullptr);
extern void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr);
extern void add_type(ID* id, IntrusivePtr<BroType> t,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr);
extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
bool is_redef, IntrusivePtr<FuncType> t,
attr_list* attrs = nullptr);
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs = nullptr);
extern void end_func(IntrusivePtr<Stmt> body);

View file

@ -167,36 +167,8 @@ static void parser_redef_enum (ID *id)
}
}
static type_decl_list* copy_type_decl_list(type_decl_list* tdl)
{
if ( ! tdl )
return 0;
type_decl_list* rval = new type_decl_list();
for ( const auto& td : *tdl )
rval->push_back(new TypeDecl(*td));
return rval;
}
static attr_list* copy_attr_list(attr_list* al)
{
if ( ! al )
return 0;
attr_list* rval = new attr_list();
for ( const auto& a : *al )
{
::Ref(a);
rval->push_back(a);
}
return rval;
}
static void extend_record(ID* id, type_decl_list* fields, attr_list* attrs)
static void extend_record(ID* id, std::unique_ptr<type_decl_list> fields,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs)
{
std::set<BroType*> types = BroType::GetAliases(id->Name());
@ -206,17 +178,19 @@ static void extend_record(ID* id, type_decl_list* fields, attr_list* attrs)
return;
}
for ( std::set<BroType*>::const_iterator it = types.begin(); it != types.end(); )
{
RecordType* add_to = (*it)->AsRecordType();
const char* error = 0;
++it;
bool add_log_attr = false;
if ( it == types.end() )
error = add_to->AddFields(fields, attrs);
else
error = add_to->AddFields(copy_type_decl_list(fields),
copy_attr_list(attrs));
if ( attrs )
for ( const auto& at : *attrs )
if ( at->Tag() == ATTR_LOG )
{
add_log_attr = true;
break;
}
for ( auto t : types )
{
auto error = t->AsRecordType()->AddFields(*fields, add_log_attr);
if ( error )
{
@ -226,6 +200,19 @@ static void extend_record(ID* id, type_decl_list* fields, attr_list* attrs)
}
}
static IntrusivePtr<Attributes>
make_attributes(std::vector<IntrusivePtr<Attr>>* attrs,
IntrusivePtr<BroType> t, bool in_record, bool is_global)
{
if ( ! attrs )
return nullptr;
auto rval = make_intrusive<Attributes>(std::move(*attrs), std::move(t),
in_record, is_global);
delete attrs;
return rval;
}
static bool expr_is_table_type_name(const Expr* expr)
{
if ( expr->Tag() != EXPR_NAME )
@ -264,7 +251,7 @@ static bool expr_is_table_type_name(const Expr* expr)
Case* c_case;
case_list* case_l;
Attr* attr;
attr_list* attr_l;
std::vector<IntrusivePtr<Attr>>* attr_l;
attr_tag attrtag;
}
@ -576,13 +563,15 @@ expr:
opt_attr
{ // the ++in_init fixes up the parsing of "[x] = y"
set_location(@1, @5);
$$ = new TableConstructorExpr({AdoptRef{}, $4}, $7);
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs{$7};
$$ = new TableConstructorExpr({AdoptRef{}, $4}, std::move(attrs));
}
| TOK_SET '(' opt_expr_list ')' opt_attr
{
set_location(@1, @4);
$$ = new SetConstructorExpr({AdoptRef{}, $3}, $5);
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs{$5};
$$ = new SetConstructorExpr({AdoptRef{}, $3}, std::move(attrs));
}
| TOK_VECTOR '(' opt_expr_list ')'
@ -1046,7 +1035,8 @@ type_decl:
TOK_ID ':' type opt_attr ';'
{
set_location(@1, @4);
$$ = new TypeDecl({AdoptRef{}, $3}, $1, $4, (in_record > 0));
auto attrs = make_attributes($4, {NewRef{}, $3}, in_record > 0, false);
$$ = new TypeDecl($1, {AdoptRef{}, $3}, std::move(attrs));
if ( in_record > 0 && cur_decl_type_id )
zeekygen_mgr->RecordField(cur_decl_type_id, $$, ::filename);
@ -1075,7 +1065,8 @@ formal_args_decl:
TOK_ID ':' type opt_attr
{
set_location(@1, @4);
$$ = new TypeDecl({AdoptRef{}, $3}, $1, $4, true);
auto attrs = make_attributes($4, {NewRef{}, $3}, true, false);
$$ = new TypeDecl($1, {AdoptRef{}, $3}, std::move(attrs));
}
;
@ -1092,21 +1083,27 @@ decl:
| TOK_GLOBAL def_global_id opt_type init_class opt_init opt_attr ';'
{
IntrusivePtr id{AdoptRef{}, $2};
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5}, $6, VAR_REGULAR);
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6},
VAR_REGULAR);
zeekygen_mgr->Identifier(std::move(id));
}
| TOK_OPTION def_global_id opt_type init_class opt_init opt_attr ';'
{
IntrusivePtr id{AdoptRef{}, $2};
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5}, $6, VAR_OPTION);
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6},
VAR_OPTION);
zeekygen_mgr->Identifier(std::move(id));
}
| TOK_CONST def_global_id opt_type init_class opt_init opt_attr ';'
{
IntrusivePtr id{AdoptRef{}, $2};
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5}, $6, VAR_CONST);
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6},
VAR_CONST);
zeekygen_mgr->Identifier(std::move(id));
}
@ -1114,7 +1111,9 @@ decl:
{
IntrusivePtr id{AdoptRef{}, $2};
IntrusivePtr<Expr> init{AdoptRef{}, $5};
add_global(id.get(), {AdoptRef{}, $3}, $4, init, $6, VAR_REDEF);
add_global(id.get(), {AdoptRef{}, $3}, $4, init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6},
VAR_REDEF);
zeekygen_mgr->Redef(id.get(), ::filename, $4, std::move(init));
}
@ -1138,7 +1137,8 @@ decl:
if ( ! $3->GetType() )
$3->Error("unknown identifier");
else
extend_record($3, $8, $11);
extend_record($3, std::unique_ptr<type_decl_list>($8),
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>($11));
}
| TOK_TYPE global_id ':'
@ -1147,7 +1147,8 @@ decl:
{
cur_decl_type_id = 0;
IntrusivePtr id{AdoptRef{}, $2};
add_type(id.get(), {AdoptRef{}, $5}, $6);
add_type(id.get(), {AdoptRef{}, $5},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6});
zeekygen_mgr->Identifier(std::move(id));
}
@ -1180,7 +1181,8 @@ func_hdr:
{
IntrusivePtr id{AdoptRef{}, $2};
begin_func(id.get(), current_module.c_str(),
FUNC_FLAVOR_FUNCTION, 0, {NewRef{}, $3}, $4);
FUNC_FLAVOR_FUNCTION, 0, {NewRef{}, $3},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$4});
$$ = $3;
zeekygen_mgr->Identifier(std::move(id));
}
@ -1194,7 +1196,8 @@ func_hdr:
}
begin_func($2, current_module.c_str(),
FUNC_FLAVOR_EVENT, 0, {NewRef{}, $3}, $4);
FUNC_FLAVOR_EVENT, 0, {NewRef{}, $3},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$4});
$$ = $3;
}
| TOK_HOOK def_global_id func_params opt_attr
@ -1202,13 +1205,15 @@ func_hdr:
$3->ClearYieldType(FUNC_FLAVOR_HOOK);
$3->SetYieldType(base_type(TYPE_BOOL));
begin_func($2, current_module.c_str(),
FUNC_FLAVOR_HOOK, 0, {NewRef{}, $3}, $4);
FUNC_FLAVOR_HOOK, 0, {NewRef{}, $3},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$4});
$$ = $3;
}
| TOK_REDEF TOK_EVENT event_id func_params opt_attr
{
begin_func($3, current_module.c_str(),
FUNC_FLAVOR_EVENT, 1, {NewRef{}, $4}, $5);
FUNC_FLAVOR_EVENT, 1, {NewRef{}, $4},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$5});
$$ = $4;
}
;
@ -1334,16 +1339,16 @@ index_slice:
opt_attr:
attr_list
|
{ $$ = 0; }
{ $$ = nullptr; }
;
attr_list:
attr_list attr
{ $1->push_back($2); }
{ $1->emplace_back(AdoptRef{}, $2); }
| attr
{
$$ = new attr_list;
$$->push_back($1);
$$ = new std::vector<IntrusivePtr<Attr>>;
$$->emplace_back(AdoptRef{}, $1);
}
;
@ -1509,7 +1514,9 @@ stmt:
{
set_location(@1, @7);
$$ = add_local({AdoptRef{}, $2}, {AdoptRef{}, $3}, $4,
{AdoptRef{}, $5}, $6, VAR_REGULAR).release();
{AdoptRef{}, $5},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6},
VAR_REGULAR).release();
if ( ! $8 )
brofiler.AddStmt($$);
}
@ -1518,7 +1525,9 @@ stmt:
{
set_location(@1, @6);
$$ = add_local({AdoptRef{}, $2}, {AdoptRef{}, $3}, $4,
{AdoptRef{}, $5}, $6, VAR_CONST).release();
{AdoptRef{}, $5},
std::unique_ptr<std::vector<IntrusivePtr<Attr>>>{$6},
VAR_CONST).release();
if ( ! $8 )
brofiler.AddStmt($$);
}
@ -1664,7 +1673,8 @@ case_type:
else
case_var = install_ID(name, current_module.c_str(), false, false);
add_local(case_var, std::move(type), INIT_NONE, 0, 0, VAR_REGULAR);
add_local(case_var, std::move(type), INIT_NONE, nullptr, nullptr,
VAR_REGULAR);
$$ = case_var.release();
}