Implement a Shallow Clone operation for types.

This is needed to track name changes for the documentation.

With this things, which do not need val-cloning, generally seem to work
again. There are a whole bunch of test failures at the moment.
This commit is contained in:
Johanna Amann 2019-05-17 11:13:04 -07:00
parent 474efe9e69
commit ffa173abc0
3 changed files with 92 additions and 12 deletions

View file

@ -121,9 +121,29 @@ BroType::BroType(TypeTag t, bool arg_base_type)
} }
BroType* BroType::Clone() const BroType* BroType::ShallowClone() const
{ {
// Fixme: Johanna switch ( tag ) {
case TYPE_VOID:
case TYPE_BOOL:
case TYPE_INT:
case TYPE_COUNT:
case TYPE_COUNTER:
case TYPE_DOUBLE:
case TYPE_TIME:
case TYPE_INTERVAL:
case TYPE_STRING:
case TYPE_PATTERN:
case TYPE_TIMER:
case TYPE_PORT:
case TYPE_ADDR:
case TYPE_SUBNET:
case TYPE_ANY:
return new BroType(tag, base_type);
default:
reporter->InternalError("cloning illegal base BroType");
}
return nullptr; return nullptr;
} }
@ -381,6 +401,16 @@ TableType::TableType(TypeList* ind, BroType* yield)
} }
} }
TableType* TableType::ShallowClone() const
{
if ( indices )
indices->Ref();
if ( yield_type )
yield_type->Ref();
return new TableType(indices, yield_type);
}
bool TableType::IsUnspecifiedTable() const bool TableType::IsUnspecifiedTable() const
{ {
// Unspecified types have an empty list of indices. // Unspecified types have an empty list of indices.
@ -488,6 +518,16 @@ FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, function_flavor arg
} }
} }
FuncType* FuncType::ShallowClone() const
{
auto f = new FuncType();
f->args = args->Ref()->AsRecordType();
f->arg_types = arg_types->Ref()->AsTypeList();
f->yield = yield->Ref();
f->flavor = flavor;
return f;
}
string FuncType::FlavorString() const string FuncType::FlavorString() const
{ {
switch ( flavor ) { switch ( flavor ) {
@ -646,6 +686,16 @@ RecordType::RecordType(type_decl_list* arg_types) : BroType(TYPE_RECORD)
num_fields = types ? types->length() : 0; num_fields = types ? types->length() : 0;
} }
// in this case the clone is actually not so shallow, since
// it gets modified by everyone.
RecordType* RecordType::ShallowClone() const
{
auto pass = new type_decl_list();
loop_over_list(*types, i)
pass->append(new TypeDecl(*(*types)[i]));
return new RecordType(pass);
}
RecordType::~RecordType() RecordType::~RecordType()
{ {
if ( types ) if ( types )
@ -991,18 +1041,26 @@ EnumType::EnumType(const string& name)
SetName(name); SetName(name);
} }
EnumType::EnumType(EnumType* e) EnumType::EnumType(const EnumType* e)
: BroType(TYPE_ENUM) : BroType(TYPE_ENUM)
{ {
counter = e->counter; counter = e->counter;
SetName(e->GetName()); SetName(e->GetName());
for ( NameMap::iterator it = e->names.begin(); it != e->names.end(); ++it ) for ( auto it = e->names.begin(); it != e->names.end(); ++it )
names[it->first] = it->second; names[it->first] = it->second;
vals = e->vals; vals = e->vals;
} }
EnumType* EnumType::ShallowClone() const
{
if ( counter == 0 )
return new EnumType(GetName());
return new EnumType(this);
}
EnumType::~EnumType() EnumType::~EnumType()
{ {
for ( auto& kv : vals ) for ( auto& kv : vals )
@ -1231,6 +1289,11 @@ VectorType::VectorType(BroType* element_type)
{ {
} }
VectorType* VectorType::ShallowClone() const
{
return new VectorType(yield_type);
}
VectorType::~VectorType() VectorType::~VectorType()
{ {
Unref(yield_type); Unref(yield_type);

View file

@ -86,7 +86,15 @@ public:
explicit BroType(TypeTag tag, bool base_type = false); explicit BroType(TypeTag tag, bool base_type = false);
~BroType() override { } ~BroType() override { }
BroType* Clone() const; // Performs a shallow clone operation of the Bro type.
// This especially means that especially for tables the types
// are not recursively cloned; altering one type will in this case
// alter one of them.
// The main use for this is alias tracking.
// Clone operations will mostly be implemented in the derived classes;
// in addition cloning will be limited to classes that can be reached by
// the script-level.
virtual BroType* ShallowClone() const;
TypeTag Tag() const { return tag; } TypeTag Tag() const { return tag; }
InternalTypeTag InternalType() const { return internal_tag; } InternalTypeTag InternalType() const { return internal_tag; }
@ -107,7 +115,7 @@ public:
// this type is a table[string] of port, then returns the "port" // this type is a table[string] of port, then returns the "port"
// type. Returns nil if this is not an index type. // type. Returns nil if this is not an index type.
virtual BroType* YieldType(); virtual BroType* YieldType();
const BroType* YieldType() const virtual const BroType* YieldType() const
{ return ((BroType*) this)->YieldType(); } { return ((BroType*) this)->YieldType(); }
// Returns true if this type is a record and contains the // Returns true if this type is a record and contains the
@ -330,7 +338,7 @@ public:
TypeList* Indices() const { return indices; } TypeList* Indices() const { return indices; }
const type_list* IndexTypes() const { return indices->Types(); } const type_list* IndexTypes() const { return indices->Types(); }
BroType* YieldType() override; BroType* YieldType() override;
const BroType* YieldType() const; const BroType* YieldType() const override;
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;
@ -356,6 +364,8 @@ class TableType : public IndexType {
public: public:
TableType(TypeList* ind, BroType* yield); TableType(TypeList* ind, BroType* yield);
TableType* ShallowClone() const override;
// Returns true if this table type is "unspecified", which is // Returns true if this table type is "unspecified", which is
// what one gets using an empty "set()" or "table()" constructor. // what one gets using an empty "set()" or "table()" constructor.
bool IsUnspecifiedTable() const; bool IsUnspecifiedTable() const;
@ -382,12 +392,13 @@ protected:
class FuncType : public BroType { class FuncType : public BroType {
public: public:
FuncType(RecordType* args, BroType* yield, function_flavor f); FuncType(RecordType* args, BroType* yield, function_flavor f);
FuncType* ShallowClone() const override;
~FuncType() override; ~FuncType() override;
RecordType* Args() const { return args; } RecordType* Args() const { return args; }
BroType* YieldType() override; BroType* YieldType() override;
const BroType* YieldType() const; const BroType* YieldType() const override;
void SetYieldType(BroType* arg_yield) { yield = arg_yield; } void SetYieldType(BroType* arg_yield) { yield = arg_yield; }
function_flavor Flavor() const { return flavor; } function_flavor Flavor() const { return flavor; }
string FlavorString() const; string FlavorString() const;
@ -405,7 +416,7 @@ public:
void DescribeReST(ODesc* d, bool roles_only = false) const override; void DescribeReST(ODesc* d, bool roles_only = false) const override;
protected: protected:
FuncType() { args = 0; arg_types = 0; yield = 0; flavor = FUNC_FLAVOR_FUNCTION; } FuncType() : BroType(TYPE_FUNC) { args = 0; arg_types = 0; yield = 0; flavor = FUNC_FLAVOR_FUNCTION; }
RecordType* args; RecordType* args;
TypeList* arg_types; TypeList* arg_types;
BroType* yield; BroType* yield;
@ -415,6 +426,7 @@ protected:
class TypeType : public BroType { class TypeType : public BroType {
public: public:
explicit TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); } explicit TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); }
TypeType* ShallowClone() const override { return new TypeType(type); }
~TypeType() override { Unref(type); } ~TypeType() override { Unref(type); }
BroType* Type() { return type; } BroType* Type() { return type; }
@ -447,6 +459,7 @@ typedef PList(TypeDecl) type_decl_list;
class RecordType : public BroType { class RecordType : public BroType {
public: public:
explicit RecordType(type_decl_list* types); explicit RecordType(type_decl_list* types);
RecordType* ShallowClone() const override;
~RecordType() override; ~RecordType() override;
@ -495,6 +508,7 @@ public:
class FileType : public BroType { class FileType : public BroType {
public: public:
explicit FileType(BroType* yield_type); explicit FileType(BroType* yield_type);
FileType* ShallowClone() const override { return new FileType(yield->Ref()); }
~FileType() override; ~FileType() override;
BroType* YieldType() override; BroType* YieldType() override;
@ -510,6 +524,7 @@ protected:
class OpaqueType : public BroType { class OpaqueType : public BroType {
public: public:
explicit OpaqueType(const string& name); explicit OpaqueType(const string& name);
OpaqueType* ShallowClone() const override { return new OpaqueType(name); }
~OpaqueType() override { }; ~OpaqueType() override { };
const string& Name() const { return name; } const string& Name() const { return name; }
@ -527,8 +542,9 @@ class EnumType : public BroType {
public: public:
typedef std::list<std::pair<string, bro_int_t> > enum_name_list; typedef std::list<std::pair<string, bro_int_t> > enum_name_list;
explicit EnumType(EnumType* e); explicit EnumType(const EnumType* e);
explicit EnumType(const string& arg_name); explicit EnumType(const string& arg_name);
EnumType* ShallowClone() const override;
~EnumType() override; ~EnumType() override;
// The value of this name is next internal counter value, starting // The value of this name is next internal counter value, starting
@ -580,9 +596,10 @@ protected:
class VectorType : public BroType { class VectorType : public BroType {
public: public:
explicit VectorType(BroType* t); explicit VectorType(BroType* t);
VectorType* ShallowClone() const override;
~VectorType() override; ~VectorType() override;
BroType* YieldType() override; BroType* YieldType() override;
const BroType* YieldType() const; const BroType* YieldType() const override;
int MatchesIndex(ListExpr*& index) const override; int MatchesIndex(ListExpr*& index) const override;

View file

@ -273,7 +273,7 @@ void add_type(ID* id, BroType* t, attr_list* attr)
tnew = t; tnew = t;
else else
// Clone the type to preserve type name aliasing. // Clone the type to preserve type name aliasing.
tnew = t->Clone(); tnew = t->ShallowClone();
BroType::AddAlias(new_type_name, tnew); BroType::AddAlias(new_type_name, tnew);