diff --git a/src/Attr.cc b/src/Attr.cc index ef82f6a412..ff3b5e8b3f 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -137,7 +137,6 @@ void Attr::AddTag(ODesc* d) const } Attributes::Attributes(attr_list* a, IntrusivePtr t, bool arg_in_record, bool is_global) - : type(std::move(t)) { attrs.reserve(a->length()); in_record = arg_in_record; @@ -155,6 +154,31 @@ Attributes::Attributes(attr_list* a, IntrusivePtr t, bool arg_in_record delete a; } +Attributes::Attributes(IntrusivePtr t, + bool arg_in_record, bool is_global) + : Attributes(std::vector>{}, std::move(t), + arg_in_record, is_global) + {} + +Attributes::Attributes(std::vector> a, + IntrusivePtr t, + bool arg_in_record, bool is_global) + : type(std::move(t)) + { + attrs.reserve(a.size()); + in_record = arg_in_record; + global_var = is_global; + + SetLocationInfo(&start_location, &end_location); + + // We loop through 'a' and add each attribute individually, + // rather than just taking over 'a' for ourselves, so that + // the necessary checking gets done. + + for ( auto& attr : a ) + AddAttr(std::move(attr)); + } + void Attributes::AddAttr(IntrusivePtr attr) { // We overwrite old attributes by deleting them first. diff --git a/src/Attr.h b/src/Attr.h index e7dfef99e1..3e90b52033 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -79,8 +79,13 @@ protected: // Manages a collection of attributes. class Attributes final : public BroObj { public: + [[deprecated("Remove in v4.1. Construct using IntrusivePtrs instead.")]] Attributes(attr_list* a, IntrusivePtr t, bool in_record, bool is_global); + Attributes(std::vector> a, IntrusivePtr t, + bool in_record, bool is_global); + Attributes(IntrusivePtr t, bool in_record, bool is_global); + void AddAttr(IntrusivePtr a); void AddAttrs(Attributes* a); // Unref's 'a' when done diff --git a/src/Expr.cc b/src/Expr.cc index 5ac4990889..672d5b4697 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3087,7 +3087,16 @@ TableConstructorExpr::TableConstructorExpr(IntrusivePtr constructor_li } } - attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : nullptr; + if ( arg_attrs ) + { + std::vector> 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 expr_list& cle = op->AsListExpr()->Exprs(); @@ -3206,7 +3215,16 @@ SetConstructorExpr::SetConstructorExpr(IntrusivePtr constructor_list, else if ( type->Tag() != TYPE_TABLE || ! type->AsTableType()->IsSet() ) SetError("values in set(...) constructor do not specify a set"); - attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : nullptr; + if ( arg_attrs ) + { + std::vector> 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(); expr_list& cle = op->AsListExpr()->Exprs(); diff --git a/src/ID.cc b/src/ID.cc index 87185eb4e9..a4a0b6f119 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -258,7 +258,7 @@ void ID::UpdateValAttrs() TypeDecl* fd = rt->FieldDecl(i); if ( ! fd->attrs ) - fd->attrs = make_intrusive(new attr_list, rt->GetFieldType(i), true, IsGlobal()); + fd->attrs = make_intrusive(rt->GetFieldType(i), true, IsGlobal()); fd->attrs->AddAttr(make_intrusive(ATTR_LOG)); } @@ -281,8 +281,8 @@ void ID::MakeDeprecated(IntrusivePtr deprecation) if ( IsDeprecated() ) return; - attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, std::move(deprecation))}; - AddAttrs(make_intrusive(attr, GetType(), false, IsGlobal())); + std::vector> attrv{make_intrusive(ATTR_DEPRECATED, std::move(deprecation))}; + AddAttrs(make_intrusive(std::move(attrv), GetType(), false, IsGlobal())); } std::string ID::GetDeprecationWarning() const @@ -331,8 +331,8 @@ void ID::SetOption() // option implied redefinable if ( ! IsRedefinable() ) { - attr_list* attr = new attr_list{new Attr(ATTR_REDEF)}; - AddAttrs(make_intrusive(attr, GetType(), false, IsGlobal())); + std::vector> attrv{make_intrusive(ATTR_REDEF)}; + AddAttrs(make_intrusive(std::move(attrv), GetType(), false, IsGlobal())); } } diff --git a/src/Type.cc b/src/Type.cc index 1c204ec052..86e901e0fe 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -609,9 +609,18 @@ std::optional FuncType::FindPrototype(const RecordType& arg TypeDecl::TypeDecl(IntrusivePtr t, const char* i, attr_list* arg_attrs, bool in_record) : type(std::move(t)), - attrs(arg_attrs ? make_intrusive(arg_attrs, type, in_record, false) : nullptr), id(i) { + if ( arg_attrs ) + { + std::vector> attrv; + + for ( auto& a : *arg_attrs ) + attrv.emplace_back(AdoptRef{}, a); + + attrs = make_intrusive(std::move(attrv), type, in_record, false); + delete arg_attrs; + } } TypeDecl::TypeDecl(const TypeDecl& other) @@ -856,7 +865,7 @@ const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) if ( log ) { if ( ! td->attrs ) - td->attrs = make_intrusive(new attr_list, td->type, true, false); + td->attrs = make_intrusive(td->type, true, false); td->attrs->AddAttr(make_intrusive(ATTR_LOG)); } diff --git a/src/Var.cc b/src/Var.cc index 1d350b737a..4ec2b6b60d 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -196,7 +196,14 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, id->SetType(t); if ( attr ) - id->AddAttrs(make_intrusive(attr, t, false, id->IsGlobal())); + { + std::vector> attrv; + + for ( auto& a : *attr) + attrv.emplace_back(AdoptRef{}, a); + + id->AddAttrs(make_intrusive(std::move(attrv), t, false, id->IsGlobal())); + } if ( init ) { @@ -387,7 +394,15 @@ void add_type(ID* id, IntrusivePtr t, attr_list* attr) id->MakeType(); if ( attr ) - id->SetAttrs(make_intrusive(attr, tnew, false, false)); + { + std::vector> attrv; + + for ( auto& a : *attr ) + attrv.emplace_back(AdoptRef{}, a); + + id->SetAttrs(make_intrusive(std::move(attrv), tnew, false, false)); + delete attr; + } } static void transfer_arg_defaults(RecordType* args, RecordType* recv) @@ -404,8 +419,10 @@ static void transfer_arg_defaults(RecordType* args, RecordType* recv) if ( ! recv_i->attrs ) { - attr_list* a = new attr_list{def}; - recv_i->attrs = make_intrusive(a, recv_i->type, true, false); + std::vector> a{{NewRef{}, def}}; + recv_i->attrs = make_intrusive(std::move(a), + recv_i->type, + true, false); } else if ( ! recv_i->attrs->FindAttr(ATTR_DEFAULT) )