diff --git a/src/Type.cc b/src/Type.cc index ce3bbc52af..e5e3103fb8 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -10,6 +10,8 @@ #include "Scope.h" #include "Serializer.h" +extern int generate_documentation; + const char* type_name(TypeTag t) { static char errbuf[512]; @@ -44,6 +46,7 @@ BroType::BroType(TypeTag t, bool arg_base_type) tag = t; is_network_order = 0; base_type = arg_base_type; + type_id = 0; switch ( tag ) { case TYPE_VOID: @@ -195,8 +198,9 @@ BroType* BroType::Unserialize(UnserialInfo* info, TypeTag want) if ( ! t ) return 0; - // For base types, we return our current instance. - if ( t->base_type ) + // For base types, we return our current instance + // if not in "documentation mode". + if ( t->base_type && ! generate_documentation ) { BroType* t2 = ::base_type(TypeTag(t->tag)); Unref(t); diff --git a/src/Type.h b/src/Type.h index fe4f7a5eb5..6dd3364ad4 100644 --- a/src/Type.h +++ b/src/Type.h @@ -206,8 +206,11 @@ public: bool Serialize(SerialInfo* info) const; static BroType* Unserialize(UnserialInfo* info, TypeTag want = TYPE_ANY); + void SetTypeID(const ID* id) { type_id = id; } + const ID* GetTypeID() const { return type_id; } + protected: - BroType() { } + BroType() { type_id = 0; } void SetError(); @@ -218,6 +221,10 @@ private: InternalTypeTag internal_tag; bool is_network_order; bool base_type; + + // This type_id field is only used by the documentation framework to + // track the names of declared types. + const ID* type_id; }; class TypeList : public BroType { diff --git a/src/Var.cc b/src/Var.cc index 04ef78c14c..324ffb05e8 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -12,6 +12,8 @@ #include "RemoteSerializer.h" #include "EventRegistry.h" +extern int generate_documentation; + static Val* init_val(Expr* init, const BroType* t, Val* aggr) { return init->InitVal(t, aggr); @@ -217,11 +219,44 @@ extern Expr* add_and_assign_local(ID* id, Expr* init, Val* val) void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */) { - id->SetType(t); + BroType* tnew = t; + + // In "documentation mode", we'd like to to be able to associate + // an identifier name with a declared type. Dealing with declared + // types that are "aliases" to a builtin type requires that the BroType + // is cloned before setting the identifier name that resolves to it. + // And still this is not enough to document cases where the declared type + // is an alias for another declared type -- but that's not a natural/common + // practice. If documenting that corner case is desired, one way + // is to add an ID* to class ID that tracks aliases and set it here if + // t->GetTypeID() is true. + if ( generate_documentation ) + { + SerializationFormat* form = new BinarySerializationFormat(); + form->StartWrite(); + CloneSerializer ss(form); + SerialInfo sinfo(&ss); + sinfo.cache = false; + + t->Serialize(&sinfo); + char* data; + uint32 len = form->EndWrite(&data); + form->StartRead(data, len); + + UnserialInfo uinfo(&ss); + uinfo.cache = false; + tnew = t->Unserialize(&uinfo); + + delete [] data; + + tnew->SetTypeID(id); + } + + id->SetType(tnew); id->MakeType(); if ( attr ) - id->SetAttrs(new Attributes(attr, t)); + id->SetAttrs(new Attributes(attr, tnew)); } void begin_func(ID* id, const char* module_name, function_flavor flavor,