Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

Type.h

Go to the documentation of this file.
00001 // $Id: Type.h,v 1.5 2004/12/06 00:16:06 vern Exp $
00002 //
00003 // Copyright (c) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003
00004 //      The Regents of the University of California.  All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that: (1) source code distributions
00008 // retain the above copyright notice and this paragraph in its entirety, (2)
00009 // distributions including binary code include the above copyright notice and
00010 // this paragraph in its entirety in the documentation or other materials
00011 // provided with the distribution, and (3) all advertising materials mentioning
00012 // features or use of this software display the following acknowledgement:
00013 // ``This product includes software developed by the University of California,
00014 // Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
00015 // the University nor the names of its contributors may be used to endorse
00016 // or promote products derived from this software without specific prior
00017 // written permission.
00018 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00019 // WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022 #ifndef type_h
00023 #define type_h
00024 
00025 #include <string>
00026 #include <map>
00027 
00028 #include "Obj.h"
00029 #include "Attr.h"
00030 #include "BroList.h"
00031 #include "Dict.h"
00032 
00033 // BRO types.
00034 
00035 typedef enum {
00036         TYPE_VOID,
00037         TYPE_BOOL, TYPE_INT, TYPE_COUNT, TYPE_COUNTER, TYPE_DOUBLE,
00038         TYPE_TIME, TYPE_INTERVAL,
00039         TYPE_STRING, TYPE_PATTERN,
00040         TYPE_ENUM,
00041         TYPE_TIMER,
00042         TYPE_PORT, TYPE_ADDR, TYPE_NET, TYPE_SUBNET,
00043         TYPE_ANY,
00044         TYPE_TABLE,
00045         TYPE_UNION,
00046         TYPE_RECORD,
00047         TYPE_LIST,
00048         TYPE_FUNC,
00049         TYPE_FILE,
00050         TYPE_VECTOR,
00051         TYPE_ERROR
00052 #define NUM_TYPES (int(TYPE_ERROR) + 1)
00053 } TypeTag;
00054 
00055 typedef enum { FUNC_FLAVOR_FUNCTION, FUNC_FLAVOR_EVENT } function_flavor;
00056 
00057 typedef enum {
00058         TYPE_INTERNAL_VOID,
00059         TYPE_INTERNAL_INT, TYPE_INTERNAL_UNSIGNED, TYPE_INTERNAL_DOUBLE,
00060         TYPE_INTERNAL_STRING, TYPE_INTERNAL_ADDR, TYPE_INTERNAL_SUBNET,
00061         TYPE_INTERNAL_OTHER, TYPE_INTERNAL_ERROR
00062 } InternalTypeTag;
00063 
00064 class Expr;
00065 class Attributes;
00066 class TypeList;
00067 class TableType;
00068 class SetType;
00069 class RecordType;
00070 class SubNetType;
00071 class FuncType;
00072 class ListExpr;
00073 class EnumType;
00074 class Serializer;
00075 class VectorType;
00076 
00077 extern bool in_global_attr_decl;
00078 extern RecordType* global_attributes_type;
00079 
00080 const int DOES_NOT_MATCH_INDEX = 0;
00081 const int MATCHES_INDEX_SCALAR = 1;
00082 const int MATCHES_INDEX_VECTOR = 2;
00083 
00084 class BroType : public BroObj {
00085 public:
00086         BroType(TypeTag tag, bool base_type = false);
00087 
00088         TypeTag Tag() const             { return tag; }
00089         InternalTypeTag InternalType() const    { return internal_tag; }
00090 
00091         // Type for the attributes (metadata) on this type.
00092         RecordType* AttributesType()
00093                 {
00094                 if ( ! attributes_type )
00095                         attributes_type = global_attributes_type;
00096                 return attributes_type;
00097                 }
00098         bool SetAttributesType(type_decl_list* attr_types);
00099 
00100         // Whether it's stored in network order.
00101         int IsNetworkOrder() const      { return is_network_order; }
00102 
00103         // Type-checks the given expression list, returning
00104         // MATCHES_INDEX_SCALAR = 1 if it matches this type's index
00105         // and produces a scalar result (and promoting its
00106         // subexpressions as necessary); MATCHES_INDEX_VECTOR = 2
00107         // if it matches and produces a vector result; and
00108         // DOES_NOT_MATCH_INDEX = 0 if it can't match (or the type
00109         // is not an indexable type).
00110         virtual int MatchesIndex(ListExpr*& index) const;
00111 
00112         // Returns the type yielded by this type.  For example, if
00113         // this type is a table[string] of port, then returns the "port"
00114         // type.  Returns nil if this is not an index type.
00115         virtual BroType* YieldType();
00116         const BroType* YieldType() const
00117                 { return ((BroType*) this)->YieldType(); }
00118 
00119         // Returns true if this type is a record and contains the
00120         // given field, false otherwise.
00121         virtual int HasField(const char* field) const;
00122 
00123         // Returns the type of the given field, or nil if no such field.
00124         virtual BroType* FieldType(const char* field) const;
00125 
00126         const TypeList* AsTypeList() const
00127                 {
00128                 if ( tag != TYPE_LIST )
00129                         BadTag("BroType::AsTypeList");
00130                 return (const TypeList*) this;
00131                 }
00132         TypeList* AsTypeList()
00133                 {
00134                 if ( tag != TYPE_LIST )
00135                         BadTag("BroType::AsTypeList");
00136                 return (TypeList*) this;
00137                 }
00138 
00139         const TableType* AsTableType() const
00140                 {
00141                 if ( tag != TYPE_TABLE )
00142                         BadTag("BroType::AsTableType");
00143                 return (const TableType*) this;
00144                 }
00145         TableType* AsTableType()
00146                 {
00147                 if ( tag != TYPE_TABLE )
00148                         BadTag("BroType::AsTableType");
00149                 return (TableType*) this;
00150                 }
00151 
00152         SetType* AsSetType()
00153                 {
00154                 if ( ! IsSet() )
00155                         BadTag("BroType::AsSetType");
00156                 return (SetType*) this;
00157                 }
00158         const SetType* AsSetType() const
00159                 {
00160                 if ( ! IsSet() )
00161                         BadTag("BroType::AsSetType");
00162                 return (const SetType*) this;
00163                 }
00164 
00165         const RecordType* AsRecordType() const
00166                 {
00167                 if ( tag != TYPE_RECORD )
00168                         BadTag("BroType::AsRecordType");
00169                 return (const RecordType*) this;
00170                 }
00171         RecordType* AsRecordType()
00172                 {
00173                 if ( tag != TYPE_RECORD )
00174                         BadTag("BroType::AsRecordType");
00175                 return (RecordType*) this;
00176                 }
00177 
00178         const SubNetType* AsSubNetType() const
00179                 {
00180                 if ( tag != TYPE_SUBNET )
00181                         BadTag("BroType::AsSubNetType");
00182                 return (const SubNetType*) this;
00183                 }
00184         SubNetType* AsSubNetType()
00185                 {
00186                 if ( tag != TYPE_SUBNET )
00187                         BadTag("BroType::AsSubNetType");
00188                 return (SubNetType*) this;
00189                 }
00190 
00191         const FuncType* AsFuncType() const
00192                 {
00193                 if ( tag != TYPE_FUNC )
00194                         BadTag("BroType::AsFuncType");
00195                 return (const FuncType*) this;
00196                 }
00197         FuncType* AsFuncType()
00198                 {
00199                 if ( tag != TYPE_FUNC )
00200                         BadTag("BroType::AsFuncType");
00201                 return (FuncType*) this;
00202                 }
00203 
00204         const EnumType* AsEnumType() const
00205                 {
00206                 if ( tag != TYPE_ENUM )
00207                         BadTag("BroType::AsEnumType");
00208                 return (EnumType*) this;
00209                 }
00210 
00211         EnumType* AsEnumType()
00212                 {
00213                 if ( tag != TYPE_ENUM )
00214                         BadTag("BroType::AsEnumType");
00215                 return (EnumType*) this;
00216                 }
00217 
00218         const VectorType* AsVectorType() const
00219                 {
00220                 if ( tag != TYPE_VECTOR )
00221                         BadTag("BroType;:AsVectorType");
00222                 return (VectorType*) this;
00223                 }
00224 
00225         VectorType* AsVectorType()
00226                 {
00227                 if ( tag != TYPE_VECTOR )
00228                         BadTag("BroType;:AsVectorType");
00229                 return (VectorType*) this;
00230                 }
00231 
00232         int IsSet() const
00233                 {
00234                 return tag == TYPE_TABLE && (YieldType() == 0);
00235                 }
00236 
00237         BroType* Ref()          { ::Ref(this); return this; }
00238 
00239         void MakeGlobalAttributeType()  { is_global_attributes_type = true; }
00240 
00241         virtual void Describe(ODesc* d) const;
00242 
00243         virtual unsigned MemoryAllocation() const;
00244 
00245         bool Serialize(SerialInfo* info) const;
00246         static BroType* Unserialize(UnserialInfo* info, TypeTag want = TYPE_ANY);
00247 
00248 protected:
00249         BroType()       { attributes_type = 0; }
00250 
00251         void SetError();
00252 
00253         DECLARE_SERIAL(BroType)
00254 
00255 private:
00256         TypeTag tag;
00257         InternalTypeTag internal_tag;
00258         bool is_network_order;
00259         bool base_type;
00260         bool is_global_attributes_type;
00261         RecordType* attributes_type;
00262 };
00263 
00264 class TypeList : public BroType {
00265 public:
00266         TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST)
00267                 {
00268                 pure_type = arg_pure_type;
00269                 if ( pure_type )
00270                         pure_type->Ref();
00271                 }
00272         ~TypeList();
00273 
00274         const type_list* Types() const  { return &types; }
00275         type_list* Types()              { return &types; }
00276 
00277         int IsPure() const              { return pure_type != 0; }
00278 
00279         // Returns the underlying pure type, or nil if the list
00280         // is not pure or is empty.
00281         BroType* PureType()             { return pure_type; }
00282         const BroType* PureType() const { return pure_type; }
00283 
00284         // True if all of the types match t, false otherwise.  If
00285         // is_init is true, then the matching is done in the context
00286         // of an initialization.
00287         int AllMatch(const BroType* t, int is_init) const;
00288 
00289         void Append(BroType* t);
00290         void AppendEvenIfNotPure(BroType* t);
00291 
00292         void Describe(ODesc* d) const;
00293 
00294         unsigned int MemoryAllocation() const
00295                 {
00296                 return BroType::MemoryAllocation()
00297                         + padded_sizeof(*this) - padded_sizeof(BroType)
00298                         + types.MemoryAllocation() - padded_sizeof(types);
00299                 }
00300 
00301 protected:
00302         DECLARE_SERIAL(TypeList)
00303 
00304         BroType* pure_type;
00305         type_list types;
00306 };
00307 
00308 class IndexType : public BroType {
00309 public:
00310         int MatchesIndex(ListExpr*& index) const;
00311 
00312         TypeList* Indices() const               { return indices; }
00313         const type_list* IndexTypes() const     { return indices->Types(); }
00314         BroType* YieldType();
00315 
00316         void Describe(ODesc* d) const;
00317 
00318         // Returns true if this table is solely indexed by subnet.
00319         bool IsSubNetIndex() const;
00320 
00321 protected:
00322         IndexType(){ indices = 0; yield_type = 0; }
00323         IndexType(TypeTag t, TypeList* arg_indices, BroType* arg_yield_type) :
00324                 BroType(t)
00325                 {
00326                 indices = arg_indices;
00327                 yield_type = arg_yield_type;
00328                 }
00329         ~IndexType();
00330 
00331         DECLARE_SERIAL(IndexType)
00332 
00333         TypeList* indices;
00334         BroType* yield_type;
00335 };
00336 
00337 class TableType : public IndexType {
00338 public:
00339         TableType(TypeList* ind, BroType* yield);
00340 
00341 protected:
00342         TableType()     {}
00343 
00344         TypeList* ExpandRecordIndex(RecordType* rt) const;
00345 
00346         DECLARE_SERIAL(TableType)
00347 };
00348 
00349 class SetType : public TableType {
00350 public:
00351         SetType(TypeList* ind, ListExpr* arg_elements);
00352         ~SetType();
00353 
00354         ListExpr* SetElements() const   { return elements; }
00355 
00356 protected:
00357         SetType()       {}
00358 
00359         ListExpr* elements;
00360 
00361         DECLARE_SERIAL(SetType)
00362 };
00363 
00364 class FuncType : public BroType {
00365 public:
00366         FuncType(RecordType* args, BroType* yield, int is_event);
00367 
00368         ~FuncType();
00369 
00370         RecordType* Args() const        { return args; }
00371         BroType* YieldType();
00372         void SetYieldType(BroType* arg_yield)   { yield = arg_yield; }
00373         int IsEvent() const             { return is_event; }
00374 
00375         // Used to convert a function type to an event type.
00376         void ClearYieldType()
00377                 { Unref(yield); yield = 0; is_event = 1; }
00378 
00379         int MatchesIndex(ListExpr*& index) const;
00380         int CheckArgs(const type_list* args) const;
00381 
00382         TypeList* ArgTypes()    { return arg_types; }
00383 
00384         ID* GetReturnValueID() const;
00385 
00386         void Describe(ODesc* d) const;
00387 
00388 protected:
00389         FuncType()      { args = 0; arg_types = 0; yield = 0; return_value = 0; }
00390         DECLARE_SERIAL(FuncType)
00391 
00392         RecordType* args;
00393         TypeList* arg_types;
00394         BroType* yield;
00395         int is_event;
00396         ID* return_value;
00397 };
00398 
00399 class TypeDecl {
00400 public:
00401         TypeDecl(BroType* t, const char* i, attr_list* attrs = 0);
00402         ~TypeDecl();
00403 
00404         const Attr* FindAttr(attr_tag a) const
00405                 { return attrs ? attrs->FindAttr(a) : 0; }
00406 
00407         bool Serialize(SerialInfo* info) const;
00408         static TypeDecl* Unserialize(UnserialInfo* info);
00409 
00410         BroType* type;
00411         Attributes* attrs;
00412         const char* id;
00413 };
00414 
00415 class RecordField {
00416 public:
00417         RecordField(int arg_base, int arg_offset, int arg_total_offset);
00418 
00419         int base;       // which base element it belongs to
00420         int offset;     // where it is in that base
00421         int total_offset;       // where it is in the aggregate record
00422 };
00423 declare(PDict,RecordField);
00424 
00425 class RecordType : public BroType {
00426 public:
00427         RecordType(type_decl_list* types);
00428         RecordType(TypeList* base, type_decl_list* refinements);
00429 
00430         ~RecordType();
00431 
00432         int HasField(const char* field) const;
00433         BroType* FieldType(const char* field) const;
00434         BroType* FieldType(int field) const;
00435 
00436         // A field's offset is its position in the type_decl_list,
00437         // starting at 0.  Returns negative if the field doesn't exist.
00438         int FieldOffset(const char* field) const;
00439 
00440         // Given an offset, returns the field's name.
00441         const char* FieldName(int field) const;
00442 
00443         // Given an offset, returns the field's TypeDecl.
00444         const TypeDecl* FieldDecl(int field) const;
00445         TypeDecl* FieldDecl(int field);
00446 
00447         int NumFields() const                   { return num_fields; }
00448 
00449         void Describe(ODesc* d) const;
00450         void DescribeFields(ODesc* d) const;
00451 
00452 protected:
00453         RecordType() { fields = 0; base = 0; types = 0; }
00454 
00455         void Init(TypeList* arg_base);
00456 
00457         DECLARE_SERIAL(RecordType)
00458 
00459         int num_fields;
00460         PDict(RecordField)* fields;
00461         TypeList* base;
00462         type_decl_list* types;
00463 };
00464 
00465 class SubNetType : public BroType {
00466 public:
00467         SubNetType();
00468         void Describe(ODesc* d) const;
00469 protected:
00470         DECLARE_SERIAL(SubNetType)
00471 };
00472 
00473 class FileType : public BroType {
00474 public:
00475         FileType(BroType* yield_type);
00476         ~FileType();
00477 
00478         BroType* YieldType();
00479 
00480         void Describe(ODesc* d) const;
00481 
00482 protected:
00483         FileType()      { yield = 0; }
00484 
00485         DECLARE_SERIAL(FileType)
00486 
00487         BroType* yield;
00488 };
00489 
00490 class EnumType : public BroType {
00491 public:
00492         EnumType(bool arg_is_export);
00493 
00494         // The value of this name is next counter value, which is returned.
00495         // A return value of -1 means that the identifier already existed
00496         // (and thus could not be used).
00497         int AddName(const string& module_name, const char* name);
00498 
00499         // Add in names from the suppled EnumType; the return value is
00500         // the value of the last enum added.
00501         int AddNamesFrom(const string& module_name, EnumType* et);
00502 
00503         // -1 indicates not found.
00504         const int Lookup(const string& module_name, const char* name);
00505         const char* Lookup(int value); // Returns 0 if not found
00506 
00507 protected:
00508         EnumType()      {}
00509 
00510         DECLARE_SERIAL(EnumType)
00511 
00512         typedef std::map< const char*, int, ltstr > NameMap;
00513         NameMap names;
00514         int counter;
00515         bool is_export;
00516 };
00517 
00518 class VectorType : public BroType {
00519 public:
00520         VectorType(BroType* t);
00521         virtual ~VectorType();
00522         BroType* YieldType()    { return yield_type; }
00523 
00524         int MatchesIndex(ListExpr*& index) const;
00525 
00526 protected:
00527         VectorType()    { yield_type = 0; }
00528 
00529         DECLARE_SERIAL(VectorType)
00530 
00531         BroType* yield_type;
00532 };
00533 
00534 
00535 // Returns the name of the type.
00536 extern const char* type_name(TypeTag t);
00537 
00538 // Returns the given type refinement, or error_type() if it's illegal.
00539 extern BroType* refine_type(TypeList* base, type_decl_list* refinements);
00540 
00541 // Returns the BRO basic (non-parameterized) type with the given type.
00542 extern BroType* base_type(TypeTag tag);
00543 
00544 // Returns the BRO basic error type.
00545 inline BroType* error_type()    { return base_type(TYPE_ERROR); }
00546 
00547 // True if the two types are equivalent.  If is_init is true then the
00548 // test is done in the context of an initialization.
00549 extern int same_type(const BroType* t1, const BroType* t2, int is_init=0);
00550 
00551 // Returns true if the record sub_rec can be promoted to the record
00552 // super_rec.
00553 extern int record_promotion_compatible(const RecordType* super_rec,
00554                                         const RecordType* sub_rec);
00555 
00556 // If the given BroType is a TypeList with just one element, returns
00557 // that element, otherwise returns the type.
00558 extern const BroType* flatten_type(const BroType* t);
00559 extern BroType* flatten_type(BroType* t);
00560 
00561 // Returns the "maximum" of two type tags, in a type-promotion sense.
00562 extern TypeTag max_type(TypeTag t1, TypeTag t2);
00563 
00564 // Given two types, returns the "merge", in which promotable types
00565 // are promoted to the maximum of the two.  Returns nil (and generates
00566 // an error message) if the types are incompatible.
00567 extern BroType* merge_types(const BroType* t1, const BroType* t2);
00568 
00569 // True if the given type tag corresponds to an integral type.
00570 #define IsIntegral(t)   (t == TYPE_INT || t == TYPE_COUNT || t == TYPE_COUNTER)
00571 
00572 // True if the given type tag corresponds to an arithmetic type.
00573 #define IsArithmetic(t) (IsIntegral(t) || t == TYPE_DOUBLE)
00574 
00575 // True if the given type tag corresponds to a boolean type.
00576 #define IsBool(t)       (t == TYPE_BOOL)
00577 
00578 // True if the given type tag corresponds to a record type.
00579 #define IsRecord(t)     (t == TYPE_RECORD || t == TYPE_UNION)
00580 
00581 // True if the given type tag corresponds to a function type.
00582 #define IsFunc(t)       (t == TYPE_FUNC)
00583 
00584 // True if the given type tag corresponds to mutable type.
00585 #define IsMutable(t)    (t == TYPE_RECORD || t == TYPE_TABLE)
00586 
00587 // True if the given type type is a vector.
00588 #define IsVector(t)     (t == TYPE_VECTOR)
00589 
00590 // True if the given type tag corresponds to type that can be assigned to.
00591 extern int is_assignable(BroType* t);
00592 
00593 // True if the given type tag corresponds to the error type.
00594 #define IsErrorType(t)  (t == TYPE_ERROR)
00595 
00596 // True if both tags are integral types.
00597 #define BothIntegral(t1, t2) (IsIntegral(t1) && IsIntegral(t2))
00598 
00599 // True if both tags are arithmetic types.
00600 #define BothArithmetic(t1, t2) (IsArithmetic(t1) && IsArithmetic(t2))
00601 
00602 // True if either tags is an arithmetic type.
00603 #define EitherArithmetic(t1, t2) (IsArithmetic(t1) || IsArithmetic(t2))
00604 
00605 // True if both tags are boolean types.
00606 #define BothBool(t1, t2) (IsBool(t1) && IsBool(t2))
00607 
00608 // True if either tag is the error type.
00609 #define EitherError(t1, t2) (IsErrorType(t1) || IsErrorType(t2))
00610 
00611 #endif

Generated on Wed Sep 14 02:56:57 2005 for bro_docs by doxygen 1.3.5