mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
restored RecordType::Create, now marked as deprecated
tidying of namespaces and private class members simplification of flagging record field initializations that should be skipped address peculiar MSVC compilation complaint for IntrusivePtr's
This commit is contained in:
parent
ee358affda
commit
c19eba62d6
5 changed files with 67 additions and 32 deletions
|
@ -28,10 +28,11 @@ struct NewRef
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This has to be forward declared and known here in order for us to be able
|
* These have to be forward-declared and known here in order for us to be able
|
||||||
* cast this in the `Unref` function.
|
* cast them in the `Unref` function.
|
||||||
*/
|
*/
|
||||||
class OpaqueVal;
|
class OpaqueVal;
|
||||||
|
class TypeVal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An intrusive, reference counting smart pointer implementation. Much like
|
* An intrusive, reference counting smart pointer implementation. Much like
|
||||||
|
@ -120,9 +121,10 @@ public:
|
||||||
{
|
{
|
||||||
if ( ptr_ )
|
if ( ptr_ )
|
||||||
{
|
{
|
||||||
// Specializing `OpaqueVal` as MSVC compiler does not detect it
|
// Specializing `Val` subclasses that the MSVC compiler
|
||||||
// inheriting from `zeek::Obj` so we have to do that manually.
|
// does not detect as inheriting from `zeek::Obj`
|
||||||
if constexpr ( std::is_same_v<T, OpaqueVal> )
|
// so we have to do that manually.
|
||||||
|
if constexpr ( std::is_same_v<T, OpaqueVal> || std::is_same_v<T, TypeVal> )
|
||||||
Unref(reinterpret_cast<zeek::Obj*>(ptr_));
|
Unref(reinterpret_cast<zeek::Obj*>(ptr_));
|
||||||
else
|
else
|
||||||
Unref(ptr_);
|
Unref(ptr_);
|
||||||
|
|
33
src/Type.cc
33
src/Type.cc
|
@ -992,6 +992,9 @@ void TypeDecl::DescribeReST(ODesc* d, bool roles_only) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
// A record field initialization that directly assigns a fixed value ...
|
// A record field initialization that directly assigns a fixed value ...
|
||||||
class DirectFieldInit final : public FieldInit
|
class DirectFieldInit final : public FieldInit
|
||||||
{
|
{
|
||||||
|
@ -1099,6 +1102,8 @@ private:
|
||||||
VectorTypePtr init_type;
|
VectorTypePtr init_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
RecordType::RecordType(type_decl_list* arg_types) : Type(TYPE_RECORD)
|
RecordType::RecordType(type_decl_list* arg_types) : Type(TYPE_RECORD)
|
||||||
{
|
{
|
||||||
types = arg_types;
|
types = arg_types;
|
||||||
|
@ -1149,7 +1154,7 @@ void RecordType::AddField(unsigned int field, const TypeDecl* td)
|
||||||
if ( field_ids.count(td->id) != 0 )
|
if ( field_ids.count(td->id) != 0 )
|
||||||
{
|
{
|
||||||
reporter->Error("duplicate field '%s' found in record definition", td->id);
|
reporter->Error("duplicate field '%s' found in record definition", td->id);
|
||||||
deferred_inits.push_back(std::nullopt);
|
deferred_inits.push_back(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1161,7 +1166,7 @@ void RecordType::AddField(unsigned int field, const TypeDecl* td)
|
||||||
auto def_attr = a ? a->Find(detail::ATTR_DEFAULT) : nullptr;
|
auto def_attr = a ? a->Find(detail::ATTR_DEFAULT) : nullptr;
|
||||||
auto def_expr = def_attr ? def_attr->GetExpr() : nullptr;
|
auto def_expr = def_attr ? def_attr->GetExpr() : nullptr;
|
||||||
|
|
||||||
std::optional<std::unique_ptr<FieldInit>> init;
|
std::unique_ptr<detail::FieldInit> init;
|
||||||
|
|
||||||
if ( def_expr && ! IsErrorType(type->Tag()) )
|
if ( def_expr && ! IsErrorType(type->Tag()) )
|
||||||
{
|
{
|
||||||
|
@ -1171,14 +1176,14 @@ void RecordType::AddField(unsigned int field, const TypeDecl* td)
|
||||||
auto zv = ZVal(v, type);
|
auto zv = ZVal(v, type);
|
||||||
|
|
||||||
if ( ZVal::IsManagedType(type) )
|
if ( ZVal::IsManagedType(type) )
|
||||||
init = std::make_unique<DirectManagedFieldInit>(zv);
|
init = std::make_unique<detail::DirectManagedFieldInit>(zv);
|
||||||
else
|
else
|
||||||
init = std::make_unique<DirectFieldInit>(zv);
|
init = std::make_unique<detail::DirectFieldInit>(zv);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto efi = std::make_unique<ExprFieldInit>(def_expr, type);
|
auto efi = std::make_unique<detail::ExprFieldInit>(def_expr, type);
|
||||||
creation_inits.emplace_back(std::make_pair(field, std::move(efi)));
|
creation_inits.emplace_back(std::make_pair(field, std::move(efi)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1188,13 +1193,13 @@ void RecordType::AddField(unsigned int field, const TypeDecl* td)
|
||||||
TypeTag tag = type->Tag();
|
TypeTag tag = type->Tag();
|
||||||
|
|
||||||
if ( tag == TYPE_RECORD )
|
if ( tag == TYPE_RECORD )
|
||||||
init = std::make_unique<RecordFieldInit>(cast_intrusive<RecordType>(type));
|
init = std::make_unique<detail::RecordFieldInit>(cast_intrusive<RecordType>(type));
|
||||||
|
|
||||||
else if ( tag == TYPE_TABLE )
|
else if ( tag == TYPE_TABLE )
|
||||||
init = std::make_unique<TableFieldInit>(cast_intrusive<TableType>(type), a);
|
init = std::make_unique<detail::TableFieldInit>(cast_intrusive<TableType>(type), a);
|
||||||
|
|
||||||
else if ( tag == TYPE_VECTOR )
|
else if ( tag == TYPE_VECTOR )
|
||||||
init = std::make_unique<VectorFieldInit>(cast_intrusive<VectorType>(type));
|
init = std::make_unique<detail::VectorFieldInit>(cast_intrusive<VectorType>(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
deferred_inits.push_back(std::move(init));
|
deferred_inits.push_back(std::move(init));
|
||||||
|
@ -1392,6 +1397,18 @@ void RecordType::AddFieldsDirectly(const type_decl_list& others, bool add_log_at
|
||||||
num_fields = types->length();
|
num_fields = types->length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RecordType::Create(std::vector<std::optional<ZVal>>& r) const
|
||||||
|
{
|
||||||
|
for ( auto& di : deferred_inits )
|
||||||
|
if ( di )
|
||||||
|
r.push_back(di->Generate());
|
||||||
|
else
|
||||||
|
r.push_back(std::nullopt);
|
||||||
|
|
||||||
|
for ( auto& ci : creation_inits )
|
||||||
|
r[ci.first] = ci.second->Generate();
|
||||||
|
}
|
||||||
|
|
||||||
void RecordType::DescribeFields(ODesc* d) const
|
void RecordType::DescribeFields(ODesc* d) const
|
||||||
{
|
{
|
||||||
if ( d->IsReadable() )
|
if ( d->IsReadable() )
|
||||||
|
|
40
src/Type.h
40
src/Type.h
|
@ -37,6 +37,16 @@ class ListExpr;
|
||||||
class Attributes;
|
class Attributes;
|
||||||
using ListExprPtr = IntrusivePtr<ListExpr>;
|
using ListExprPtr = IntrusivePtr<ListExpr>;
|
||||||
|
|
||||||
|
// The following tracks how to initialize a given record field.
|
||||||
|
class FieldInit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~FieldInit() { }
|
||||||
|
|
||||||
|
// Return the initialization value of the field.
|
||||||
|
virtual ZVal Generate() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// Zeek types.
|
// Zeek types.
|
||||||
|
@ -601,17 +611,6 @@ public:
|
||||||
|
|
||||||
using type_decl_list = PList<TypeDecl>;
|
using type_decl_list = PList<TypeDecl>;
|
||||||
|
|
||||||
// The following tracks how to initialize a given field.
|
|
||||||
|
|
||||||
class FieldInit
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~FieldInit() { }
|
|
||||||
|
|
||||||
// Return the initialization value of the field.
|
|
||||||
virtual ZVal Generate() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RecordType final : public Type
|
class RecordType final : public Type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -690,6 +689,15 @@ public:
|
||||||
|
|
||||||
void AddFieldsDirectly(const type_decl_list& types, bool add_log_attr = false);
|
void AddFieldsDirectly(const type_decl_list& types, bool add_log_attr = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Populates a new instance of the record with its initial values.
|
||||||
|
* @param r The record's underlying value vector.
|
||||||
|
*/
|
||||||
|
[[deprecated("Remove in v6.1. Construct a corresponding RecordVal and build vector from "
|
||||||
|
"GetFieldAs() calls.")]] void
|
||||||
|
Create(std::vector<std::optional<ZVal>>& r) const;
|
||||||
|
|
||||||
void DescribeReST(ODesc* d, bool roles_only = false) const override;
|
void DescribeReST(ODesc* d, bool roles_only = false) const override;
|
||||||
void DescribeFields(ODesc* d) const;
|
void DescribeFields(ODesc* d) const;
|
||||||
void DescribeFieldsReST(ODesc* d, bool func_args) const;
|
void DescribeFieldsReST(ODesc* d, bool func_args) const;
|
||||||
|
@ -710,7 +718,7 @@ public:
|
||||||
|
|
||||||
detail::TraversalCode Traverse(detail::TraversalCallback* cb) const override;
|
detail::TraversalCode Traverse(detail::TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
RecordType() { types = nullptr; }
|
RecordType() { types = nullptr; }
|
||||||
|
|
||||||
void AddField(unsigned int field, const TypeDecl* td);
|
void AddField(unsigned int field, const TypeDecl* td);
|
||||||
|
@ -718,9 +726,9 @@ protected:
|
||||||
void DoDescribe(ODesc* d) const override;
|
void DoDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
// Field initializations that can be deferred to first access,
|
// Field initializations that can be deferred to first access,
|
||||||
// beneficial for fields that are separately iniitialized prior
|
// beneficial for fields that are separately initialized prior
|
||||||
// to first access.
|
// to first access. Nil pointers mean "skip initializing the field".
|
||||||
std::vector<std::optional<std::unique_ptr<FieldInit>>> deferred_inits;
|
std::vector<std::unique_ptr<detail::FieldInit>> deferred_inits;
|
||||||
|
|
||||||
// Field initializations that need to be done upon record creation,
|
// Field initializations that need to be done upon record creation,
|
||||||
// rather than deferred. These are expressions whose value might
|
// rather than deferred. These are expressions whose value might
|
||||||
|
@ -728,7 +736,7 @@ protected:
|
||||||
//
|
//
|
||||||
// Such initializations are uncommon, so we represent them using
|
// Such initializations are uncommon, so we represent them using
|
||||||
// <fieldoffset, init> pairs.
|
// <fieldoffset, init> pairs.
|
||||||
std::vector<std::pair<int, std::unique_ptr<FieldInit>>> creation_inits;
|
std::vector<std::pair<int, std::unique_ptr<detail::FieldInit>>> creation_inits;
|
||||||
|
|
||||||
friend zeek::RecordVal;
|
friend zeek::RecordVal;
|
||||||
const auto& DeferredInits() const { return deferred_inits; }
|
const auto& DeferredInits() const { return deferred_inits; }
|
||||||
|
|
|
@ -2778,6 +2778,14 @@ RecordVal::RecordVal(RecordTypePtr t, bool init_fields) : Val(t), is_managed(t->
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following is just for testing the deprecated Create()
|
||||||
|
// call, and can be removed with 6.1. We leave it commented
|
||||||
|
// out so we don't get deprecation warnings when building.
|
||||||
|
#if 0
|
||||||
|
std::vector<std::optional<ZVal>> testing;
|
||||||
|
rt->Create(testing);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
|
@ -1218,7 +1218,7 @@ public:
|
||||||
if ( (*record_val)[field] )
|
if ( (*record_val)[field] )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return bool(rt->DeferredInits()[field]);
|
return rt->DeferredInits()[field] != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1247,7 +1247,7 @@ public:
|
||||||
if ( ! fi )
|
if ( ! fi )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
fv = (*fi)->Generate();
|
fv = fi->Generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return fv->ToVal(rt->GetFieldType(field));
|
return fv->ToVal(rt->GetFieldType(field));
|
||||||
|
@ -1458,7 +1458,7 @@ protected:
|
||||||
{
|
{
|
||||||
const auto& fi = rt->DeferredInits()[field];
|
const auto& fi = rt->DeferredInits()[field];
|
||||||
if ( fi )
|
if ( fi )
|
||||||
f = (*fi)->Generate();
|
f = fi->Generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue