diff --git a/src/Type.cc b/src/Type.cc index f252aea70f..fc0c9ef43a 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -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; } @@ -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 { // 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 { switch ( flavor ) { @@ -646,6 +686,16 @@ RecordType::RecordType(type_decl_list* arg_types) : BroType(TYPE_RECORD) 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() { if ( types ) @@ -991,18 +1041,26 @@ EnumType::EnumType(const string& name) SetName(name); } -EnumType::EnumType(EnumType* e) +EnumType::EnumType(const EnumType* e) : BroType(TYPE_ENUM) { counter = e->counter; 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; vals = e->vals; } +EnumType* EnumType::ShallowClone() const + { + if ( counter == 0 ) + return new EnumType(GetName()); + + return new EnumType(this); + } + EnumType::~EnumType() { for ( auto& kv : vals ) @@ -1231,6 +1289,11 @@ VectorType::VectorType(BroType* element_type) { } +VectorType* VectorType::ShallowClone() const + { + return new VectorType(yield_type); + } + VectorType::~VectorType() { Unref(yield_type); diff --git a/src/Type.h b/src/Type.h index 4825feeb2f..9af6c9c96f 100644 --- a/src/Type.h +++ b/src/Type.h @@ -86,7 +86,15 @@ public: explicit BroType(TypeTag tag, bool base_type = false); ~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; } InternalTypeTag InternalType() const { return internal_tag; } @@ -107,7 +115,7 @@ public: // this type is a table[string] of port, then returns the "port" // type. Returns nil if this is not an index type. virtual BroType* YieldType(); - const BroType* YieldType() const + virtual const BroType* YieldType() const { return ((BroType*) this)->YieldType(); } // Returns true if this type is a record and contains the @@ -330,7 +338,7 @@ public: TypeList* Indices() const { return indices; } const type_list* IndexTypes() const { return indices->Types(); } BroType* YieldType() override; - const BroType* YieldType() const; + const BroType* YieldType() const override; void Describe(ODesc* d) const override; void DescribeReST(ODesc* d, bool roles_only = false) const override; @@ -356,6 +364,8 @@ class TableType : public IndexType { public: TableType(TypeList* ind, BroType* yield); + TableType* ShallowClone() const override; + // Returns true if this table type is "unspecified", which is // what one gets using an empty "set()" or "table()" constructor. bool IsUnspecifiedTable() const; @@ -382,12 +392,13 @@ protected: class FuncType : public BroType { public: FuncType(RecordType* args, BroType* yield, function_flavor f); + FuncType* ShallowClone() const override; ~FuncType() override; RecordType* Args() const { return args; } BroType* YieldType() override; - const BroType* YieldType() const; + const BroType* YieldType() const override; void SetYieldType(BroType* arg_yield) { yield = arg_yield; } function_flavor Flavor() const { return flavor; } string FlavorString() const; @@ -405,7 +416,7 @@ public: void DescribeReST(ODesc* d, bool roles_only = false) const override; 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; TypeList* arg_types; BroType* yield; @@ -415,6 +426,7 @@ protected: class TypeType : public BroType { public: explicit TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); } + TypeType* ShallowClone() const override { return new TypeType(type); } ~TypeType() override { Unref(type); } BroType* Type() { return type; } @@ -447,6 +459,7 @@ typedef PList(TypeDecl) type_decl_list; class RecordType : public BroType { public: explicit RecordType(type_decl_list* types); + RecordType* ShallowClone() const override; ~RecordType() override; @@ -495,6 +508,7 @@ public: class FileType : public BroType { public: explicit FileType(BroType* yield_type); + FileType* ShallowClone() const override { return new FileType(yield->Ref()); } ~FileType() override; BroType* YieldType() override; @@ -510,6 +524,7 @@ protected: class OpaqueType : public BroType { public: explicit OpaqueType(const string& name); + OpaqueType* ShallowClone() const override { return new OpaqueType(name); } ~OpaqueType() override { }; const string& Name() const { return name; } @@ -527,8 +542,9 @@ class EnumType : public BroType { public: typedef std::list > enum_name_list; - explicit EnumType(EnumType* e); + explicit EnumType(const EnumType* e); explicit EnumType(const string& arg_name); + EnumType* ShallowClone() const override; ~EnumType() override; // The value of this name is next internal counter value, starting @@ -580,9 +596,10 @@ protected: class VectorType : public BroType { public: explicit VectorType(BroType* t); + VectorType* ShallowClone() const override; ~VectorType() override; BroType* YieldType() override; - const BroType* YieldType() const; + const BroType* YieldType() const override; int MatchesIndex(ListExpr*& index) const override; diff --git a/src/Var.cc b/src/Var.cc index 3c056ae194..f0cae1224c 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -273,7 +273,7 @@ void add_type(ID* id, BroType* t, attr_list* attr) tnew = t; else // Clone the type to preserve type name aliasing. - tnew = t->Clone(); + tnew = t->ShallowClone(); BroType::AddAlias(new_type_name, tnew);