Branch data Line data Source code
1 : : // $Id: Type.h 6916 2009-09-24 20:48:36Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef type_h
6 : : #define type_h
7 : :
8 : : #include <string>
9 : : #include <map>
10 : :
11 : : #include "Obj.h"
12 : : #include "Attr.h"
13 : : #include "BroList.h"
14 : : #include "Dict.h"
15 : :
16 : : // BRO types.
17 : :
18 : : typedef enum {
19 : : TYPE_VOID,
20 : : TYPE_BOOL, TYPE_INT, TYPE_COUNT, TYPE_COUNTER, TYPE_DOUBLE,
21 : : TYPE_TIME, TYPE_INTERVAL,
22 : : TYPE_STRING, TYPE_PATTERN,
23 : : TYPE_ENUM,
24 : : TYPE_TIMER,
25 : : TYPE_PORT, TYPE_ADDR, TYPE_NET, TYPE_SUBNET,
26 : : TYPE_ANY,
27 : : TYPE_TABLE,
28 : : TYPE_UNION,
29 : : TYPE_RECORD,
30 : : TYPE_LIST,
31 : : TYPE_FUNC,
32 : : TYPE_FILE,
33 : : TYPE_VECTOR,
34 : : TYPE_ERROR
35 : : #define NUM_TYPES (int(TYPE_ERROR) + 1)
36 : : } TypeTag;
37 : :
38 : : typedef enum { FUNC_FLAVOR_FUNCTION, FUNC_FLAVOR_EVENT } function_flavor;
39 : :
40 : : typedef enum {
41 : : TYPE_INTERNAL_VOID,
42 : : TYPE_INTERNAL_INT, TYPE_INTERNAL_UNSIGNED, TYPE_INTERNAL_DOUBLE,
43 : : TYPE_INTERNAL_STRING, TYPE_INTERNAL_ADDR, TYPE_INTERNAL_SUBNET,
44 : : TYPE_INTERNAL_OTHER, TYPE_INTERNAL_ERROR
45 : : } InternalTypeTag;
46 : :
47 : : // Returns the name of the type.
48 : : extern const char* type_name(TypeTag t);
49 : :
50 : : class Expr;
51 : : class Attributes;
52 : : class TypeList;
53 : : class TableType;
54 : : class SetType;
55 : : class RecordType;
56 : : class SubNetType;
57 : : class FuncType;
58 : : class ListExpr;
59 : : class EnumType;
60 : : class Serializer;
61 : : class VectorType;
62 : :
63 : : extern bool in_global_attr_decl;
64 : : extern RecordType* global_attributes_type;
65 : :
66 : : const int DOES_NOT_MATCH_INDEX = 0;
67 : : const int MATCHES_INDEX_SCALAR = 1;
68 : : const int MATCHES_INDEX_VECTOR = 2;
69 : :
70 [ - + ][ # # ]: 145133 : class BroType : public BroObj {
[ # # ]
71 : : public:
72 : : BroType(TypeTag tag, bool base_type = false);
73 : :
74 : 6867700 : TypeTag Tag() const { return tag; }
75 : 2060528 : InternalTypeTag InternalType() const { return internal_tag; }
76 : :
77 : : // Type for the attributes (metadata) on this type.
78 : 0 : RecordType* AttributesType()
79 : : {
80 [ # # ]: 0 : if ( ! attributes_type )
81 : 0 : attributes_type = global_attributes_type;
82 : 0 : return attributes_type;
83 : : }
84 : : bool SetAttributesType(type_decl_list* attr_types);
85 : :
86 : : // Whether it's stored in network order.
87 : 10852 : int IsNetworkOrder() const { return is_network_order; }
88 : :
89 : : // Type-checks the given expression list, returning
90 : : // MATCHES_INDEX_SCALAR = 1 if it matches this type's index
91 : : // and produces a scalar result (and promoting its
92 : : // subexpressions as necessary); MATCHES_INDEX_VECTOR = 2
93 : : // if it matches and produces a vector result; and
94 : : // DOES_NOT_MATCH_INDEX = 0 if it can't match (or the type
95 : : // is not an indexable type).
96 : : virtual int MatchesIndex(ListExpr*& index) const;
97 : :
98 : : // Returns the type yielded by this type. For example, if
99 : : // this type is a table[string] of port, then returns the "port"
100 : : // type. Returns nil if this is not an index type.
101 : : virtual BroType* YieldType();
102 : 38622 : const BroType* YieldType() const
103 : 38622 : { return ((BroType*) this)->YieldType(); }
104 : :
105 : : // Returns true if this type is a record and contains the
106 : : // given field, false otherwise.
107 : : virtual int HasField(const char* field) const;
108 : :
109 : : // Returns the type of the given field, or nil if no such field.
110 : : virtual BroType* FieldType(const char* field) const;
111 : :
112 : : #define CHECK_TYPE_TAG(tag_type, func_name) \
113 : : CHECK_TAG(tag, tag_type, func_name, type_name)
114 : :
115 : 4904 : const TypeList* AsTypeList() const
116 : : {
117 [ - + ]: 4904 : CHECK_TYPE_TAG(TYPE_LIST, "BroType::AsTypeList");
118 : 4904 : return (const TypeList*) this;
119 : : }
120 : 307959 : TypeList* AsTypeList()
121 : : {
122 [ - + ]: 307959 : CHECK_TYPE_TAG(TYPE_LIST, "BroType::AsTypeList");
123 : 307959 : return (TypeList*) this;
124 : : }
125 : :
126 : 0 : const TableType* AsTableType() const
127 : : {
128 [ # # ]: 0 : CHECK_TYPE_TAG(TYPE_TABLE, "BroType::AsTableType");
129 : 0 : return (const TableType*) this;
130 : : }
131 : 47156 : TableType* AsTableType()
132 : : {
133 [ - + ]: 47156 : CHECK_TYPE_TAG(TYPE_TABLE, "BroType::AsTableType");
134 : 47156 : return (TableType*) this;
135 : : }
136 : :
137 : 256 : SetType* AsSetType()
138 : : {
139 [ - + ]: 256 : if ( ! IsSet() )
140 : 0 : BadTag("BroType::AsSetType", type_name(tag));
141 : 256 : return (SetType*) this;
142 : : }
143 : 26 : const SetType* AsSetType() const
144 : : {
145 [ - + ]: 26 : if ( ! IsSet() )
146 : 0 : BadTag("BroType::AsSetType", type_name(tag));
147 : 26 : return (const SetType*) this;
148 : : }
149 : :
150 : 86 : const RecordType* AsRecordType() const
151 : : {
152 [ - + ]: 86 : CHECK_TYPE_TAG(TYPE_RECORD, "BroType::AsRecordType");
153 : 86 : return (const RecordType*) this;
154 : : }
155 : 55814 : RecordType* AsRecordType()
156 : : {
157 [ - + ]: 55814 : CHECK_TYPE_TAG(TYPE_RECORD, "BroType::AsRecordType");
158 : 55814 : return (RecordType*) this;
159 : : }
160 : :
161 : : const SubNetType* AsSubNetType() const
162 : : {
163 : : CHECK_TYPE_TAG(TYPE_SUBNET, "BroType::AsSubNetType");
164 : : return (const SubNetType*) this;
165 : : }
166 : : SubNetType* AsSubNetType()
167 : : {
168 : : CHECK_TYPE_TAG(TYPE_SUBNET, "BroType::AsSubNetType");
169 : : return (SubNetType*) this;
170 : : }
171 : :
172 : : const FuncType* AsFuncType() const
173 : : {
174 : : CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType");
175 : : return (const FuncType*) this;
176 : : }
177 : 172072 : FuncType* AsFuncType()
178 : : {
179 [ - + ]: 172072 : CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType");
180 : 172072 : return (FuncType*) this;
181 : : }
182 : :
183 : : const EnumType* AsEnumType() const
184 : : {
185 : : CHECK_TYPE_TAG(TYPE_ENUM, "BroType::AsEnumType");
186 : : return (EnumType*) this;
187 : : }
188 : :
189 : 8602 : EnumType* AsEnumType()
190 : : {
191 [ - + ]: 8602 : CHECK_TYPE_TAG(TYPE_ENUM, "BroType::AsEnumType");
192 : 8602 : return (EnumType*) this;
193 : : }
194 : :
195 : : const VectorType* AsVectorType() const
196 : : {
197 : : CHECK_TYPE_TAG(TYPE_VECTOR, "BroType::AsVectorType");
198 : : return (VectorType*) this;
199 : : }
200 : :
201 : 26283 : VectorType* AsVectorType()
202 : : {
203 [ - + ]: 26283 : CHECK_TYPE_TAG(TYPE_VECTOR, "BroType::AsVectorType");
204 : 26283 : return (VectorType*) this;
205 : : }
206 : :
207 : 45326 : int IsSet() const
208 : : {
209 [ + + ][ + + ]: 45326 : return tag == TYPE_TABLE && (YieldType() == 0);
210 : : }
211 : :
212 : 1085874 : BroType* Ref() { ::Ref(this); return this; }
213 : :
214 : 3 : void MakeGlobalAttributeType() { is_global_attributes_type = true; }
215 : :
216 : : virtual void Describe(ODesc* d) const;
217 : :
218 : : virtual unsigned MemoryAllocation() const;
219 : :
220 : : bool Serialize(SerialInfo* info) const;
221 : : static BroType* Unserialize(UnserialInfo* info, TypeTag want = TYPE_ANY);
222 : :
223 : : protected:
224 : 0 : BroType() { attributes_type = 0; }
225 : :
226 : : void SetError();
227 : :
228 : 32 : DECLARE_SERIAL(BroType)
229 : :
230 : : private:
231 : : TypeTag tag;
232 : : InternalTypeTag internal_tag;
233 : : bool is_network_order;
234 : : bool base_type;
235 : : bool is_global_attributes_type;
236 : : RecordType* attributes_type;
237 : : };
238 : :
239 : : class TypeList : public BroType {
240 : : public:
241 : 156512 : TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST)
242 : : {
243 : 156512 : pure_type = arg_pure_type;
244 [ + + ]: 156512 : if ( pure_type )
245 : 1350 : pure_type->Ref();
246 : 156512 : }
247 : : ~TypeList();
248 : :
249 : 4201 : const type_list* Types() const { return &types; }
250 : 94974 : type_list* Types() { return &types; }
251 : :
252 : 157533 : int IsPure() const { return pure_type != 0; }
253 : :
254 : : // Returns the underlying pure type, or nil if the list
255 : : // is not pure or is empty.
256 : 63 : BroType* PureType() { return pure_type; }
257 : 2447 : const BroType* PureType() const { return pure_type; }
258 : :
259 : : // True if all of the types match t, false otherwise. If
260 : : // is_init is true, then the matching is done in the context
261 : : // of an initialization.
262 : : int AllMatch(const BroType* t, int is_init) const;
263 : :
264 : : void Append(BroType* t);
265 : : void AppendEvenIfNotPure(BroType* t);
266 : :
267 : : void Describe(ODesc* d) const;
268 : :
269 : 0 : unsigned int MemoryAllocation() const
270 : : {
271 : : return BroType::MemoryAllocation()
272 : : + padded_sizeof(*this) - padded_sizeof(BroType)
273 : 0 : + types.MemoryAllocation() - padded_sizeof(types);
274 : : }
275 : :
276 : : protected:
277 : 6 : DECLARE_SERIAL(TypeList)
278 : :
279 : : BroType* pure_type;
280 : : type_list types;
281 : : };
282 : :
283 : : class IndexType : public BroType {
284 : : public:
285 : : int MatchesIndex(ListExpr*& index) const;
286 : :
287 : 19571 : TypeList* Indices() const { return indices; }
288 : 130 : const type_list* IndexTypes() const { return indices->Types(); }
289 : : BroType* YieldType();
290 : :
291 : : void Describe(ODesc* d) const;
292 : :
293 : : // Returns true if this table is solely indexed by subnet.
294 : : bool IsSubNetIndex() const;
295 : :
296 : : protected:
297 : 0 : IndexType(){ indices = 0; yield_type = 0; }
298 : 1272 : IndexType(TypeTag t, TypeList* arg_indices, BroType* arg_yield_type) :
299 : 1272 : BroType(t)
300 : : {
301 : 1272 : indices = arg_indices;
302 : 1272 : yield_type = arg_yield_type;
303 : 1272 : }
304 : : ~IndexType();
305 : :
306 : 0 : DECLARE_SERIAL(IndexType)
307 : :
308 : : TypeList* indices;
309 : : BroType* yield_type;
310 : : };
311 : :
312 [ + - ][ # # ]: 361 : class TableType : public IndexType {
[ # # ]
313 : : public:
314 : : TableType(TypeList* ind, BroType* yield);
315 : :
316 : : // Returns true if this table type is "unspecified", which is
317 : : // what one gets using an empty "set()" or "table()" constructor.
318 : : bool IsUnspecifiedTable() const;
319 : :
320 : : protected:
321 : 0 : TableType() {}
322 : :
323 : : TypeList* ExpandRecordIndex(RecordType* rt) const;
324 : :
325 : 7 : DECLARE_SERIAL(TableType)
326 : : };
327 : :
328 : : class SetType : public TableType {
329 : : public:
330 : : SetType(TypeList* ind, ListExpr* arg_elements);
331 : : ~SetType();
332 : :
333 : 251 : ListExpr* SetElements() const { return elements; }
334 : :
335 : : protected:
336 : 0 : SetType() {}
337 : :
338 : : ListExpr* elements;
339 : :
340 : 0 : DECLARE_SERIAL(SetType)
341 : : };
342 : :
343 : : class FuncType : public BroType {
344 : : public:
345 : : FuncType(RecordType* args, BroType* yield, int is_event);
346 : :
347 : : ~FuncType();
348 : :
349 : 2370 : RecordType* Args() const { return args; }
350 : : BroType* YieldType();
351 : 5 : void SetYieldType(BroType* arg_yield) { yield = arg_yield; }
352 : 3378 : int IsEvent() const { return is_event; }
353 : :
354 : : // Used to convert a function type to an event type.
355 : 575 : void ClearYieldType()
356 : 575 : { Unref(yield); yield = 0; is_event = 1; }
357 : :
358 : : int MatchesIndex(ListExpr*& index) const;
359 : : int CheckArgs(const type_list* args) const;
360 : :
361 : 2 : TypeList* ArgTypes() { return arg_types; }
362 : :
363 : : ID* GetReturnValueID() const;
364 : :
365 : : void Describe(ODesc* d) const;
366 : :
367 : : protected:
368 : 0 : FuncType() { args = 0; arg_types = 0; yield = 0; return_value = 0; }
369 : 2 : DECLARE_SERIAL(FuncType)
370 : :
371 : : RecordType* args;
372 : : TypeList* arg_types;
373 : : BroType* yield;
374 : : int is_event;
375 : : ID* return_value;
376 : : };
377 : :
378 : : class TypeDecl {
379 : : public:
380 : : TypeDecl(BroType* t, const char* i, attr_list* attrs = 0);
381 : : ~TypeDecl();
382 : :
383 : 5800 : const Attr* FindAttr(attr_tag a) const
384 [ + - ]: 5800 : { return attrs ? attrs->FindAttr(a) : 0; }
385 : :
386 : : bool Serialize(SerialInfo* info) const;
387 : : static TypeDecl* Unserialize(UnserialInfo* info);
388 : :
389 : : BroType* type;
390 : : Attributes* attrs;
391 : : const char* id;
392 : : };
393 : :
394 : : class RecordField {
395 : : public:
396 : : RecordField(int arg_base, int arg_offset, int arg_total_offset);
397 : :
398 : : int base; // which base element it belongs to
399 : : int offset; // where it is in that base
400 : : int total_offset; // where it is in the aggregate record
401 : : };
402 [ # # ][ # # ]: 0 : declare(PDict,RecordField);
403 : :
404 : : class RecordType : public BroType {
405 : : public:
406 : : RecordType(type_decl_list* types);
407 : : RecordType(TypeList* base, type_decl_list* refinements);
408 : :
409 : : ~RecordType();
410 : :
411 : : int HasField(const char* field) const;
412 : : BroType* FieldType(const char* field) const;
413 : : BroType* FieldType(int field) const;
414 : :
415 : : // A field's offset is its position in the type_decl_list,
416 : : // starting at 0. Returns negative if the field doesn't exist.
417 : : int FieldOffset(const char* field) const;
418 : :
419 : : // Given an offset, returns the field's name.
420 : : const char* FieldName(int field) const;
421 : :
422 : : // Given an offset, returns the field's TypeDecl.
423 : : const TypeDecl* FieldDecl(int field) const;
424 : : TypeDecl* FieldDecl(int field);
425 : :
426 : 80725 : int NumFields() const { return num_fields; }
427 : :
428 : : void Describe(ODesc* d) const;
429 : : void DescribeFields(ODesc* d) const;
430 : :
431 : : protected:
432 : 0 : RecordType() { fields = 0; base = 0; types = 0; }
433 : :
434 : : void Init(TypeList* arg_base);
435 : :
436 : 17 : DECLARE_SERIAL(RecordType)
437 : :
438 : : int num_fields;
439 : : PDict(RecordField)* fields;
440 : : TypeList* base;
441 : : type_decl_list* types;
442 : : };
443 : :
444 [ # # ][ # # ]: 0 : class SubNetType : public BroType {
445 : : public:
446 : : SubNetType();
447 : : void Describe(ODesc* d) const;
448 : : protected:
449 : 0 : DECLARE_SERIAL(SubNetType)
450 : : };
451 : :
452 : : class FileType : public BroType {
453 : : public:
454 : : FileType(BroType* yield_type);
455 : : ~FileType();
456 : :
457 : : BroType* YieldType();
458 : :
459 : : void Describe(ODesc* d) const;
460 : :
461 : : protected:
462 : 0 : FileType() { yield = 0; }
463 : :
464 : 0 : DECLARE_SERIAL(FileType)
465 : :
466 : : BroType* yield;
467 : : };
468 : :
469 : : class EnumType : public BroType {
470 : : public:
471 : : EnumType(bool arg_is_export);
472 : : ~EnumType();
473 : :
474 : : // The value of this name is next counter value, which is returned.
475 : : // A return value of -1 means that the identifier already existed
476 : : // (and thus could not be used).
477 : : int AddName(const string& module_name, const char* name);
478 : :
479 : : // Add in names from the suppled EnumType; the return value is
480 : : // the value of the last enum added.
481 : : int AddNamesFrom(const string& module_name, EnumType* et);
482 : :
483 : : // -1 indicates not found.
484 : : int Lookup(const string& module_name, const char* name);
485 : : const char* Lookup(int value); // Returns 0 if not found
486 : :
487 : : protected:
488 : 0 : EnumType() {}
489 : :
490 : 0 : DECLARE_SERIAL(EnumType)
491 : :
492 : : typedef std::map< const char*, int, ltstr > NameMap;
493 : : NameMap names;
494 : : int counter;
495 : : bool is_export;
496 : : };
497 : :
498 : : class VectorType : public BroType {
499 : : public:
500 : : VectorType(BroType* t);
501 : : virtual ~VectorType();
502 : 45294 : BroType* YieldType() { return yield_type; }
503 : :
504 : : int MatchesIndex(ListExpr*& index) const;
505 : :
506 : : protected:
507 : 0 : VectorType() { yield_type = 0; }
508 : :
509 : 0 : DECLARE_SERIAL(VectorType)
510 : :
511 : : BroType* yield_type;
512 : : };
513 : :
514 : :
515 : : // Returns the given type refinement, or error_type() if it's illegal.
516 : : extern BroType* refine_type(TypeList* base, type_decl_list* refinements);
517 : :
518 : : // Returns the BRO basic (non-parameterized) type with the given type.
519 : : extern BroType* base_type(TypeTag tag);
520 : :
521 : : // Returns the BRO basic error type.
522 : 0 : inline BroType* error_type() { return base_type(TYPE_ERROR); }
523 : :
524 : : // True if the two types are equivalent. If is_init is true then the
525 : : // test is done in the context of an initialization.
526 : : extern int same_type(const BroType* t1, const BroType* t2, int is_init=0);
527 : :
528 : : // Returns true if the record sub_rec can be promoted to the record
529 : : // super_rec.
530 : : extern int record_promotion_compatible(const RecordType* super_rec,
531 : : const RecordType* sub_rec);
532 : :
533 : : // If the given BroType is a TypeList with just one element, returns
534 : : // that element, otherwise returns the type.
535 : : extern const BroType* flatten_type(const BroType* t);
536 : : extern BroType* flatten_type(BroType* t);
537 : :
538 : : // Returns the "maximum" of two type tags, in a type-promotion sense.
539 : : extern TypeTag max_type(TypeTag t1, TypeTag t2);
540 : :
541 : : // Given two types, returns the "merge", in which promotable types
542 : : // are promoted to the maximum of the two. Returns nil (and generates
543 : : // an error message) if the types are incompatible.
544 : : extern BroType* merge_types(const BroType* t1, const BroType* t2);
545 : :
546 : : // Given a list of expressions, returns a (ref'd) type reflecting
547 : : // a merged type consistent across all of them, or nil if this
548 : : // cannot be done.
549 : : BroType* merge_type_list(ListExpr* elements);
550 : :
551 : : // Given an expression, infer its type when used for an initialization.
552 : : extern BroType* init_type(Expr* init);
553 : :
554 : : // True if the given type tag corresponds to an integral type.
555 : : #define IsIntegral(t) (t == TYPE_INT || t == TYPE_COUNT || t == TYPE_COUNTER)
556 : :
557 : : // True if the given type tag corresponds to an arithmetic type.
558 : : #define IsArithmetic(t) (IsIntegral(t) || t == TYPE_DOUBLE)
559 : :
560 : : // True if the given type tag corresponds to a boolean type.
561 : : #define IsBool(t) (t == TYPE_BOOL)
562 : :
563 : : // True if the given type tag corresponds to an interval type.
564 : : #define IsInterval(t) (t == TYPE_INTERVAL)
565 : :
566 : : // True if the given type tag corresponds to a record type.
567 : : #define IsRecord(t) (t == TYPE_RECORD || t == TYPE_UNION)
568 : :
569 : : // True if the given type tag corresponds to a function type.
570 : : #define IsFunc(t) (t == TYPE_FUNC)
571 : :
572 : : // True if the given type tag corresponds to mutable type.
573 : : #define IsMutable(t) \
574 : : (t == TYPE_RECORD || t == TYPE_TABLE || t == TYPE_VECTOR)
575 : :
576 : : // True if the given type type is a vector.
577 : : #define IsVector(t) (t == TYPE_VECTOR)
578 : :
579 : : // True if the given type type is a string.
580 : : #define IsString(t) (t == TYPE_STRING)
581 : :
582 : : // True if the given type tag corresponds to type that can be assigned to.
583 : : extern int is_assignable(BroType* t);
584 : :
585 : : // True if the given type tag corresponds to the error type.
586 : : #define IsErrorType(t) (t == TYPE_ERROR)
587 : :
588 : : // True if both tags are integral types.
589 : : #define BothIntegral(t1, t2) (IsIntegral(t1) && IsIntegral(t2))
590 : :
591 : : // True if both tags are arithmetic types.
592 : : #define BothArithmetic(t1, t2) (IsArithmetic(t1) && IsArithmetic(t2))
593 : :
594 : : // True if either tags is an arithmetic type.
595 : : #define EitherArithmetic(t1, t2) (IsArithmetic(t1) || IsArithmetic(t2))
596 : :
597 : : // True if both tags are boolean types.
598 : : #define BothBool(t1, t2) (IsBool(t1) && IsBool(t2))
599 : :
600 : : // True if both tags are interval types.
601 : : #define BothInterval(t1, t2) (IsInterval(t1) && IsInterval(t2))
602 : :
603 : : // True if both tags are string types.
604 : : #define BothString(t1, t2) (IsString(t1) && IsString(t2))
605 : :
606 : : // True if either tag is the error type.
607 : : #define EitherError(t1, t2) (IsErrorType(t1) || IsErrorType(t2))
608 : :
609 : : #endif
|