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, AssignExpr::AssignExpr(IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2,
bool arg_is_init, IntrusivePtr<Val> arg_val, bool arg_is_init, IntrusivePtr<Val> arg_val,
attr_list* arg_attrs) const IntrusivePtr<Attributes>& attrs)
: BinaryExpr(EXPR_ASSIGN, arg_is_init ? : BinaryExpr(EXPR_ASSIGN, arg_is_init ?
std::move(arg_op1) : arg_op1->MakeLvalue(), std::move(arg_op1) : arg_op1->MakeLvalue(),
std::move(arg_op2)) 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 // We discard the status from TypeCheck since it has already
// generated error messages. // generated error messages.
(void) TypeCheck(arg_attrs); (void) TypeCheck(attrs);
val = std::move(arg_val); val = std::move(arg_val);
SetLocationInfo(op1->GetLocationInfo(), op2->GetLocationInfo()); SetLocationInfo(op1->GetLocationInfo(), op2->GetLocationInfo());
} }
bool AssignExpr::TypeCheck(attr_list* attrs) bool AssignExpr::TypeCheck(const IntrusivePtr<Attributes>& attrs)
{ {
TypeTag bt1 = op1->GetType()->Tag(); TypeTag bt1 = op1->GetType()->Tag();
TypeTag bt2 = op2->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 ) if ( bt1 == TYPE_TABLE && op2->Tag() == EXPR_LIST )
{ {
attr_list* attr_copy = nullptr; std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr_copy;
if ( attrs ) if ( attrs )
{ attr_copy = std::make_unique<std::vector<IntrusivePtr<Attr>>>(attrs->Attrs());
attr_copy = new attr_list(attrs->length());
std::copy(attrs->begin(), attrs->end(), std::back_inserter(*attr_copy));
}
bool empty_list_assignment = (op2->AsListExpr()->Exprs().empty()); bool empty_list_assignment = (op2->AsListExpr()->Exprs().empty());
if ( op1->GetType()->IsSet() ) if ( op1->GetType()->IsSet() )
op2 = make_intrusive<SetConstructorExpr>( op2 = make_intrusive<SetConstructorExpr>(
IntrusivePtr{NewRef{}, op2->AsListExpr()}, attr_copy); cast_intrusive<ListExpr>(op2), std::move(attr_copy));
else else
op2 = make_intrusive<TableConstructorExpr>( 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()) ) if ( ! empty_list_assignment && ! same_type(op1->GetType(), op2->GetType()) )
{ {
@ -2166,23 +2163,19 @@ bool AssignExpr::TypeCheck(attr_list* attrs)
return false; return false;
} }
attr_list* attr_copy = nullptr; std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr_copy;
if ( sce->Attrs() )
{
const auto& a = sce->Attrs()->Attrs();
attr_copy = new attr_list(a.size());
for ( const auto& attr : a ) if ( sce->GetAttrs() )
{ {
::Ref(attr.get()); const auto& a = sce->GetAttrs()->Attrs();
attrs->push_back(attr.get()); attr_copy = std::make_unique<std::vector<IntrusivePtr<Attr>>>(a);
}
} }
int errors_before = reporter->Errors(); int errors_before = reporter->Errors();
op2 = make_intrusive<SetConstructorExpr>( op2 = make_intrusive<SetConstructorExpr>(
IntrusivePtr{NewRef{}, ctor_list}, attr_copy, IntrusivePtr{NewRef{}, ctor_list},
std::move(attr_copy),
op1->GetType()); op1->GetType());
int errors_after = reporter->Errors(); int errors_after = reporter->Errors();
@ -2286,7 +2279,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const
if ( IsError() ) if ( IsError() )
return; return;
TypeDecl td(nullptr, nullptr); TypeDecl td;
if ( IsRecordElement(&td) ) if ( IsRecordElement(&td) )
{ {
@ -2341,7 +2334,7 @@ IntrusivePtr<Val> AssignExpr::InitVal(const BroType* t, IntrusivePtr<Val> aggr)
if ( IsError() ) if ( IsError() )
return nullptr; return nullptr;
TypeDecl td(nullptr, nullptr); TypeDecl td;
if ( IsRecordElement(&td) ) if ( IsRecordElement(&td) )
{ {
@ -2997,7 +2990,7 @@ RecordConstructorExpr::RecordConstructorExpr(IntrusivePtr<ListExpr> constructor_
FieldAssignExpr* field = (FieldAssignExpr*) e; FieldAssignExpr* field = (FieldAssignExpr*) e;
const auto& field_type = field->GetType(); const auto& field_type = field->GetType();
char* field_name = copy_string(field->FieldName()); 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)); SetType(make_intrusive<RecordType>(record_types));
@ -3051,10 +3044,9 @@ void RecordConstructorExpr::ExprDescribe(ODesc* d) const
} }
TableConstructorExpr::TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list, TableConstructorExpr::TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
attr_list* arg_attrs, std::unique_ptr<std::vector<IntrusivePtr<Attr>>> arg_attrs,
IntrusivePtr<BroType> arg_type) IntrusivePtr<BroType> arg_type)
: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, std::move(constructor_list)), : UnaryExpr(EXPR_TABLE_CONSTRUCTOR, std::move(constructor_list))
attrs(nullptr)
{ {
if ( IsError() ) if ( IsError() )
return; return;
@ -3088,15 +3080,7 @@ TableConstructorExpr::TableConstructorExpr(IntrusivePtr<ListExpr> constructor_li
} }
if ( arg_attrs ) if ( arg_attrs )
{ attrs = make_intrusive<Attributes>(std::move(*arg_attrs), type, false, false);
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;
}
const auto& indices = type->AsTableType()->GetIndices()->Types(); const auto& indices = type->AsTableType()->GetIndices()->Types();
const expr_list& cle = op->AsListExpr()->Exprs(); const expr_list& cle = op->AsListExpr()->Exprs();
@ -3144,8 +3128,7 @@ IntrusivePtr<Val> TableConstructorExpr::Eval(Frame* f) const
if ( IsError() ) if ( IsError() )
return nullptr; return nullptr;
auto aggr = make_intrusive<TableVal>(GetType<TableType>(), auto aggr = make_intrusive<TableVal>(GetType<TableType>(), attrs);
IntrusivePtr{NewRef{}, attrs});
const expr_list& exprs = op->AsListExpr()->Exprs(); const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& expr : exprs ) for ( const auto& expr : exprs )
@ -3165,7 +3148,7 @@ IntrusivePtr<Val> TableConstructorExpr::InitVal(const BroType* t, IntrusivePtr<V
auto tval = aggr ? auto tval = aggr ?
IntrusivePtr<TableVal>{AdoptRef{}, aggr.release()->AsTableVal()} : 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(); const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& expr : exprs ) for ( const auto& expr : exprs )
@ -3182,10 +3165,9 @@ void TableConstructorExpr::ExprDescribe(ODesc* d) const
} }
SetConstructorExpr::SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list, SetConstructorExpr::SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
attr_list* arg_attrs, std::unique_ptr<std::vector<IntrusivePtr<Attr>>> arg_attrs,
IntrusivePtr<BroType> arg_type) IntrusivePtr<BroType> arg_type)
: UnaryExpr(EXPR_SET_CONSTRUCTOR, std::move(constructor_list)), : UnaryExpr(EXPR_SET_CONSTRUCTOR, std::move(constructor_list))
attrs(nullptr)
{ {
if ( IsError() ) if ( IsError() )
return; return;
@ -3216,15 +3198,7 @@ SetConstructorExpr::SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
SetError("values in set(...) constructor do not specify a set"); SetError("values in set(...) constructor do not specify a set");
if ( arg_attrs ) if ( arg_attrs )
{ attrs = make_intrusive<Attributes>(std::move(*arg_attrs), type, false, false);
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;
}
const auto& indices = type->AsTableType()->GetIndices()->Types(); const auto& indices = type->AsTableType()->GetIndices()->Types();
expr_list& cle = op->AsListExpr()->Exprs(); expr_list& cle = op->AsListExpr()->Exprs();
@ -3264,7 +3238,7 @@ IntrusivePtr<Val> SetConstructorExpr::Eval(Frame* f) const
return nullptr; return nullptr;
auto aggr = make_intrusive<TableVal>(IntrusivePtr{NewRef{}, type->AsTableType()}, auto aggr = make_intrusive<TableVal>(IntrusivePtr{NewRef{}, type->AsTableType()},
IntrusivePtr{NewRef{}, attrs}); attrs);
const expr_list& exprs = op->AsListExpr()->Exprs(); const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& expr : exprs ) for ( const auto& expr : exprs )
@ -3285,7 +3259,7 @@ IntrusivePtr<Val> SetConstructorExpr::InitVal(const BroType* t, IntrusivePtr<Val
auto tt = GetType<TableType>(); auto tt = GetType<TableType>();
auto tval = aggr ? auto tval = aggr ?
IntrusivePtr<TableVal>{AdoptRef{}, aggr.release()->AsTableVal()} : 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(); const expr_list& exprs = op->AsListExpr()->Exprs();
for ( const auto& e : 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 // If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers. // yet still perform the assignment. Used for triggers.
AssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, bool is_init, 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; IntrusivePtr<Val> Eval(Frame* f) const override;
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override; void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
@ -529,7 +530,7 @@ public:
bool IsPure() const override; bool IsPure() const override;
protected: protected:
bool TypeCheck(attr_list* attrs = nullptr); bool TypeCheck(const IntrusivePtr<Attributes>& attrs = nullptr);
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2); bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
bool is_init; bool is_init;
@ -630,11 +631,15 @@ protected:
class TableConstructorExpr final : public UnaryExpr { class TableConstructorExpr final : public UnaryExpr {
public: 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); 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; IntrusivePtr<Val> Eval(Frame* f) const override;
@ -643,16 +648,20 @@ protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Attributes* attrs; IntrusivePtr<Attributes> attrs;
}; };
class SetConstructorExpr final : public UnaryExpr { class SetConstructorExpr final : public UnaryExpr {
public: 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); 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; IntrusivePtr<Val> Eval(Frame* f) const override;
@ -661,7 +670,7 @@ protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Attributes* attrs; IntrusivePtr<Attributes> attrs;
}; };
class VectorConstructorExpr final : public UnaryExpr { 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 // Gets a function's priority from its Scope's attributes. Errors if it sees any
// problems. // problems.
static int get_func_priority(const attr_list& attrs) static int get_func_priority(const std::vector<IntrusivePtr<Attr>>& attrs)
{ {
int priority = 0; int priority = 0;
@ -883,7 +883,7 @@ function_ingredients::function_ingredients(IntrusivePtr<Scope> scope, IntrusiveP
this->scope = std::move(scope); this->scope = std::move(scope);
id = {NewRef{}, this->scope->ScopeID()}; id = {NewRef{}, this->scope->ScopeID()};
auto attrs = this->scope->Attrs(); const auto& attrs = this->scope->Attrs();
priority = (attrs ? get_func_priority(*attrs) : 0); priority = (attrs ? get_func_priority(*attrs) : 0);
this->body = std::move(body); this->body = std::move(body);

View file

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

View file

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

View file

@ -607,21 +607,12 @@ std::optional<FuncType::Prototype> FuncType::FindPrototype(const RecordType& arg
return {}; 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)), : type(std::move(t)),
attrs(std::move(arg_attrs)),
id(i) 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) TypeDecl::TypeDecl(const TypeDecl& other)
{ {
@ -832,35 +823,24 @@ IntrusivePtr<TableVal> RecordType::GetRecordFieldsVal(const RecordVal* rv) const
return rval; 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); assert(types);
bool log = false; bool log = false;
if ( attr ) for ( const auto& td : others )
{
for ( const auto& at : *attr )
{
if ( at->Tag() == ATTR_LOG )
log = true;
}
}
for ( const auto& td : *others )
{ {
if ( ! td->GetAttr(ATTR_DEFAULT) && ! td->GetAttr(ATTR_OPTIONAL) ) if ( ! td->GetAttr(ATTR_DEFAULT) && ! td->GetAttr(ATTR_OPTIONAL) )
{
delete others;
return "extension field must be &optional or have &default"; return "extension field must be &optional or have &default";
} }
}
TableVal::SaveParseTimeTableState(this); TableVal::SaveParseTimeTableState(this);
for ( const auto& td : *others ) for ( const auto& td : others )
{ {
if ( log ) if ( add_log_attr )
{ {
if ( ! td->attrs ) if ( ! td->attrs )
td->attrs = make_intrusive<Attributes>(td->type, true, false); 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); types->push_back(td);
} }
delete others;
num_fields = types->length(); num_fields = types->length();
RecordVal::ResizeParseTimeRecords(this); RecordVal::ResizeParseTimeRecords(this);
TableVal::RebuildParseTimeTables(); TableVal::RebuildParseTimeTables();
@ -1878,7 +1856,7 @@ IntrusivePtr<BroType> merge_types(const IntrusivePtr<BroType>& arg_t1,
return nullptr; 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); return make_intrusive<RecordType>(tdl3);

View file

@ -562,7 +562,8 @@ protected:
class TypeDecl final { class TypeDecl final {
public: 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(const TypeDecl& other);
~TypeDecl(); ~TypeDecl();
@ -577,7 +578,7 @@ public:
IntrusivePtr<BroType> type; IntrusivePtr<BroType> type;
IntrusivePtr<Attributes> attrs; IntrusivePtr<Attributes> attrs;
const char* id; const char* id = nullptr;
}; };
typedef PList<TypeDecl> type_decl_list; typedef PList<TypeDecl> type_decl_list;
@ -656,9 +657,9 @@ public:
*/ */
IntrusivePtr<TableVal> GetRecordFieldsVal(const RecordVal* rv = nullptr) const; IntrusivePtr<TableVal> GetRecordFieldsVal(const RecordVal* rv = nullptr) const;
// Returns 0 if all is ok, otherwise a pointer to an error message. // Returns null if all is ok, otherwise a pointer to an error message.
// Takes ownership of list. const char* AddFields(const type_decl_list& types,
const char* AddFields(type_decl_list* types, attr_list* attr); bool add_log_attr = false);
void Describe(ODesc* d) const override; void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d, bool roles_only = false) 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) const IntrusivePtr<Expr>& init)
{ {
if ( ! IsFunc(id->GetType()->Tag()) ) 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, 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) bool do_init)
{ {
if ( id->GetType() ) 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 ) else if ( dt != VAR_REDEF || init || ! attr )
{ {
if ( IsFunc(id->GetType()->Tag()) ) if ( IsFunc(id->GetType()->Tag()) )
add_prototype(id, t.get(), attr, init); add_prototype(id, t.get(), attr.get(), init);
else else
id->Error("already defined", init.get()); 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); id->SetType(t);
if ( attr ) if ( attr )
{ id->AddAttrs(make_intrusive<Attributes>(std::move(*attr), t, false, id->IsGlobal()));
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()));
}
if ( init ) if ( init )
{ {
@ -211,16 +207,16 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
case EXPR_TABLE_CONSTRUCTOR: case EXPR_TABLE_CONSTRUCTOR:
{ {
TableConstructorExpr* ctor = (TableConstructorExpr*) init.get(); TableConstructorExpr* ctor = (TableConstructorExpr*) init.get();
if ( ctor->Attrs() ) if ( ctor->GetAttrs() )
id->AddAttrs({NewRef{}, ctor->Attrs()}); id->AddAttrs(ctor->GetAttrs());
} }
break; break;
case EXPR_SET_CONSTRUCTOR: case EXPR_SET_CONSTRUCTOR:
{ {
SetConstructorExpr* ctor = (SetConstructorExpr*) init.get(); SetConstructorExpr* ctor = (SetConstructorExpr*) init.get();
if ( ctor->Attrs() ) if ( ctor->GetAttrs() )
id->AddAttrs({NewRef{}, ctor->Attrs()}); id->AddAttrs(ctor->GetAttrs());
} }
break; 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, 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, IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
init_class c, IntrusivePtr<Expr> init, 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 ) if ( init )
{ {
@ -333,20 +332,9 @@ IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
*init->GetLocationInfo() : no_location; *init->GetLocationInfo() : no_location;
auto name_expr = make_intrusive<NameExpr>(id, dt == VAR_CONST); 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), auto assign_expr = make_intrusive<AssignExpr>(std::move(name_expr),
std::move(init), 0, std::move(init), 0,
nullptr, attrs); nullptr, id->GetAttrs());
delete attrs;
auto stmt = make_intrusive<ExprStmt>(std::move(assign_expr)); auto stmt = make_intrusive<ExprStmt>(std::move(assign_expr));
stmt->SetLocationInfo(&location); stmt->SetLocationInfo(&location);
return stmt; return stmt;
@ -369,7 +357,8 @@ extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
false, std::move(val)); 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 new_type_name = id->Name();
std::string old_type_name = t->GetName(); std::string old_type_name = t->GetName();
@ -394,15 +383,7 @@ void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
id->MakeType(); id->MakeType();
if ( attr ) if ( attr )
{ id->SetAttrs(make_intrusive<Attributes>(std::move(*attr), tnew, false, false));
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;
}
} }
static void transfer_arg_defaults(RecordType* args, RecordType* recv) 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 ) if ( ! al )
return nullptr; return nullptr;
for ( int i = 0; i < al->length(); ++i ) for ( size_t i = 0; i < al->size(); ++i )
if ( (*al)[i]->Tag() == tag ) if ( (*al)[i]->Tag() == tag )
return (*al)[i]; return (*al)[i].get();
return nullptr; 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) static std::optional<FuncType::Prototype> func_type_check(const FuncType* decl, const FuncType* impl)
{ {
if ( decl->Flavor() != impl->Flavor() ) 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, 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 ) if ( flavor == FUNC_FLAVOR_EVENT )
{ {
@ -580,7 +557,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
else else
id->SetType(t); id->SetType(t);
push_scope({NewRef{}, id}, attrs); push_scope({NewRef{}, id}, std::move(attrs));
const auto& args = t->Params(); const auto& args = t->Params();
int num_args = args->NumFields(); 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]); 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()); 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; typedef enum { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, } decl_type;
extern void add_global(ID* id, IntrusivePtr<BroType> t, init_class c, extern void add_global(ID* id,
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt); 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, extern IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id,
IntrusivePtr<BroType> t, init_class c, IntrusivePtr<BroType> t,
IntrusivePtr<Expr> init, attr_list* attr, init_class c,
IntrusivePtr<Expr> init,
std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attr,
decl_type dt); decl_type dt);
extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id, extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
IntrusivePtr<Expr> init, IntrusivePtr<Expr> init,
IntrusivePtr<Val> val = nullptr); 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, extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
bool is_redef, IntrusivePtr<FuncType> t, 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); 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) static void extend_record(ID* id, std::unique_ptr<type_decl_list> fields,
{ std::unique_ptr<std::vector<IntrusivePtr<Attr>>> attrs)
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)
{ {
std::set<BroType*> types = BroType::GetAliases(id->Name()); 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; return;
} }
for ( std::set<BroType*>::const_iterator it = types.begin(); it != types.end(); ) bool add_log_attr = false;
{
RecordType* add_to = (*it)->AsRecordType();
const char* error = 0;
++it;
if ( it == types.end() ) if ( attrs )
error = add_to->AddFields(fields, attrs); for ( const auto& at : *attrs )
else if ( at->Tag() == ATTR_LOG )
error = add_to->AddFields(copy_type_decl_list(fields), {
copy_attr_list(attrs)); add_log_attr = true;
break;
}
for ( auto t : types )
{
auto error = t->AsRecordType()->AddFields(*fields, add_log_attr);
if ( error ) 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) static bool expr_is_table_type_name(const Expr* expr)
{ {
if ( expr->Tag() != EXPR_NAME ) if ( expr->Tag() != EXPR_NAME )
@ -264,7 +251,7 @@ static bool expr_is_table_type_name(const Expr* expr)
Case* c_case; Case* c_case;
case_list* case_l; case_list* case_l;
Attr* attr; Attr* attr;
attr_list* attr_l; std::vector<IntrusivePtr<Attr>>* attr_l;
attr_tag attrtag; attr_tag attrtag;
} }
@ -576,13 +563,15 @@ expr:
opt_attr opt_attr
{ // the ++in_init fixes up the parsing of "[x] = y" { // the ++in_init fixes up the parsing of "[x] = y"
set_location(@1, @5); 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 | TOK_SET '(' opt_expr_list ')' opt_attr
{ {
set_location(@1, @4); 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 ')' | TOK_VECTOR '(' opt_expr_list ')'
@ -1046,7 +1035,8 @@ type_decl:
TOK_ID ':' type opt_attr ';' TOK_ID ':' type opt_attr ';'
{ {
set_location(@1, @4); 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 ) if ( in_record > 0 && cur_decl_type_id )
zeekygen_mgr->RecordField(cur_decl_type_id, $$, ::filename); zeekygen_mgr->RecordField(cur_decl_type_id, $$, ::filename);
@ -1075,7 +1065,8 @@ formal_args_decl:
TOK_ID ':' type opt_attr TOK_ID ':' type opt_attr
{ {
set_location(@1, @4); 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 ';' | TOK_GLOBAL def_global_id opt_type init_class opt_init opt_attr ';'
{ {
IntrusivePtr id{AdoptRef{}, $2}; 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)); zeekygen_mgr->Identifier(std::move(id));
} }
| TOK_OPTION def_global_id opt_type init_class opt_init opt_attr ';' | TOK_OPTION def_global_id opt_type init_class opt_init opt_attr ';'
{ {
IntrusivePtr id{AdoptRef{}, $2}; 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)); zeekygen_mgr->Identifier(std::move(id));
} }
| TOK_CONST def_global_id opt_type init_class opt_init opt_attr ';' | TOK_CONST def_global_id opt_type init_class opt_init opt_attr ';'
{ {
IntrusivePtr id{AdoptRef{}, $2}; 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)); zeekygen_mgr->Identifier(std::move(id));
} }
@ -1114,7 +1111,9 @@ decl:
{ {
IntrusivePtr id{AdoptRef{}, $2}; IntrusivePtr id{AdoptRef{}, $2};
IntrusivePtr<Expr> init{AdoptRef{}, $5}; 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)); zeekygen_mgr->Redef(id.get(), ::filename, $4, std::move(init));
} }
@ -1138,7 +1137,8 @@ decl:
if ( ! $3->GetType() ) if ( ! $3->GetType() )
$3->Error("unknown identifier"); $3->Error("unknown identifier");
else 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 ':' | TOK_TYPE global_id ':'
@ -1147,7 +1147,8 @@ decl:
{ {
cur_decl_type_id = 0; cur_decl_type_id = 0;
IntrusivePtr id{AdoptRef{}, $2}; 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)); zeekygen_mgr->Identifier(std::move(id));
} }
@ -1180,7 +1181,8 @@ func_hdr:
{ {
IntrusivePtr id{AdoptRef{}, $2}; IntrusivePtr id{AdoptRef{}, $2};
begin_func(id.get(), current_module.c_str(), 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; $$ = $3;
zeekygen_mgr->Identifier(std::move(id)); zeekygen_mgr->Identifier(std::move(id));
} }
@ -1194,7 +1196,8 @@ func_hdr:
} }
begin_func($2, current_module.c_str(), 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; $$ = $3;
} }
| TOK_HOOK def_global_id func_params opt_attr | TOK_HOOK def_global_id func_params opt_attr
@ -1202,13 +1205,15 @@ func_hdr:
$3->ClearYieldType(FUNC_FLAVOR_HOOK); $3->ClearYieldType(FUNC_FLAVOR_HOOK);
$3->SetYieldType(base_type(TYPE_BOOL)); $3->SetYieldType(base_type(TYPE_BOOL));
begin_func($2, current_module.c_str(), 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; $$ = $3;
} }
| TOK_REDEF TOK_EVENT event_id func_params opt_attr | TOK_REDEF TOK_EVENT event_id func_params opt_attr
{ {
begin_func($3, current_module.c_str(), 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; $$ = $4;
} }
; ;
@ -1334,16 +1339,16 @@ index_slice:
opt_attr: opt_attr:
attr_list attr_list
| |
{ $$ = 0; } { $$ = nullptr; }
; ;
attr_list: attr_list:
attr_list attr attr_list attr
{ $1->push_back($2); } { $1->emplace_back(AdoptRef{}, $2); }
| attr | attr
{ {
$$ = new attr_list; $$ = new std::vector<IntrusivePtr<Attr>>;
$$->push_back($1); $$->emplace_back(AdoptRef{}, $1);
} }
; ;
@ -1509,7 +1514,9 @@ stmt:
{ {
set_location(@1, @7); set_location(@1, @7);
$$ = add_local({AdoptRef{}, $2}, {AdoptRef{}, $3}, $4, $$ = 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 ) if ( ! $8 )
brofiler.AddStmt($$); brofiler.AddStmt($$);
} }
@ -1518,7 +1525,9 @@ stmt:
{ {
set_location(@1, @6); set_location(@1, @6);
$$ = add_local({AdoptRef{}, $2}, {AdoptRef{}, $3}, $4, $$ = 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 ) if ( ! $8 )
brofiler.AddStmt($$); brofiler.AddStmt($$);
} }
@ -1664,7 +1673,8 @@ case_type:
else else
case_var = install_ID(name, current_module.c_str(), false, false); 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(); $$ = case_var.release();
} }