Branch data Line data Source code
1 : : // $Id: Expr.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 expr_h
6 : : #define expr_h
7 : :
8 : : // BRO expressions.
9 : :
10 : : #include "BroList.h"
11 : : #include "ID.h"
12 : : #include "Timer.h"
13 : : #include "Val.h"
14 : : #include "Debug.h"
15 : : #include "EventHandler.h"
16 : : #include "TraverseTypes.h"
17 : :
18 : : typedef enum {
19 : : EXPR_ANY = -1,
20 : : EXPR_NAME, EXPR_CONST,
21 : : EXPR_CLONE,
22 : : EXPR_INCR, EXPR_DECR, EXPR_NOT, EXPR_POSITIVE, EXPR_NEGATE,
23 : : EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
24 : : EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
25 : : EXPR_AND, EXPR_OR,
26 : : EXPR_LT, EXPR_LE, EXPR_EQ, EXPR_NE, EXPR_GE, EXPR_GT,
27 : : EXPR_COND,
28 : : EXPR_REF,
29 : : EXPR_ASSIGN,
30 : : EXPR_MATCH,
31 : : EXPR_INDEX,
32 : : EXPR_FIELD, EXPR_HAS_FIELD,
33 : : EXPR_RECORD_CONSTRUCTOR,
34 : : EXPR_TABLE_CONSTRUCTOR,
35 : : EXPR_SET_CONSTRUCTOR,
36 : : EXPR_VECTOR_CONSTRUCTOR,
37 : : EXPR_FIELD_ASSIGN,
38 : : EXPR_IN,
39 : : EXPR_LIST,
40 : : EXPR_CALL,
41 : : EXPR_EVENT,
42 : : EXPR_SCHEDULE,
43 : : EXPR_ARITH_COERCE, EXPR_RECORD_COERCE, EXPR_TABLE_COERCE,
44 : : EXPR_SIZE,
45 : : EXPR_FLATTEN,
46 : : #define NUM_EXPRS (int(EXPR_FLATTEN) + 1)
47 : : } BroExprTag;
48 : :
49 : : typedef enum {
50 : : SIMPLIFY_GENERAL, // regular simplification
51 : : SIMPLIFY_LHS, // simplify as the LHS of an assignment
52 : : } SimplifyType;
53 : :
54 : : extern const char* expr_name(BroExprTag t);
55 : :
56 : : class Stmt;
57 : : class Frame;
58 : : class ListExpr;
59 : : class CallExpr;
60 : : class EventExpr;
61 : :
62 : :
63 : : class Expr : public BroObj {
64 : : public:
65 : 428797 : BroType* Type() const { return type; }
66 : 18330 : BroExprTag Tag() const { return tag; }
67 : :
68 : : virtual ~Expr();
69 : :
70 : 1012 : Expr* Ref() { ::Ref(this); return this; }
71 : :
72 : : // Returns a fully simplified version of the expression (this
73 : : // may be the same expression, or a newly created one). simp_type
74 : : // gives the context of the simplification.
75 : : virtual Expr* Simplify(SimplifyType simp_type) = 0;
76 : :
77 : : // Evaluates the expression and returns a corresponding Val*,
78 : : // or nil if the expression's value isn't fixed.
79 : : virtual Val* Eval(Frame* f) const = 0;
80 : :
81 : : // Same, but the context is that we are adding an element
82 : : // into the given aggregate of the given type. Note that
83 : : // return type is void since it's updating an existing
84 : : // value, rather than creating a new one.
85 : : virtual void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f)
86 : : const;
87 : :
88 : : // Assign to the given value, if appropriate.
89 : : virtual void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
90 : :
91 : : // Returns the type corresponding to this expression interpreted
92 : : // as an initialization. The type should be Unref()'d when done
93 : : // using it. Returns nil if the initialization is illegal.
94 : : virtual BroType* InitType() const;
95 : :
96 : : // Returns true if this expression, interpreted as an initialization,
97 : : // constitutes a record element, false otherwise. If the TypeDecl*
98 : : // is non-nil and the expression is a record element, fills in the
99 : : // TypeDecl with a description of the element.
100 : : virtual int IsRecordElement(TypeDecl* td) const;
101 : :
102 : : // Returns a value corresponding to this expression interpreted
103 : : // as an initialization, or nil if the expression is inconsistent
104 : : // with the given type. If "aggr" is non-nil, then this expression
105 : : // is an element of the given aggregate, and it is added to it
106 : : // accordingly.
107 : : virtual Val* InitVal(const BroType* t, Val* aggr) const;
108 : :
109 : : // True if the expression has no side effects, false otherwise.
110 : : virtual int IsPure() const;
111 : :
112 : : // True if the expression is a constant, false otherwise.
113 : 283 : int IsConst() const { return tag == EXPR_CONST; }
114 : :
115 : : // True if the expression is in error (to alleviate error propagation).
116 [ + + ][ - + ]: 888087 : int IsError() const { return type && type->Tag() == TYPE_ERROR; }
117 : :
118 : : // Mark expression as in error.
119 : 0 : void SetError() { SetType(error_type()); }
120 : : void SetError(const char* msg);
121 : :
122 : : // Returns the expression's constant value, or complains
123 : : // if it's not a constant.
124 : : inline Val* ExprVal() const;
125 : :
126 : : // True if the expression is a constant zero, false otherwise.
127 : 5 : int IsZero() const
128 : : {
129 [ + - ][ + - ]: 5 : return IsConst() && ExprVal()->IsZero();
130 : : }
131 : :
132 : : // True if the expression is a constant one, false otherwise.
133 : 0 : int IsOne() const
134 : : {
135 [ # # ][ # # ]: 0 : return IsConst() && ExprVal()->IsOne();
136 : : }
137 : :
138 : : // True if the expression supports the "add" or "delete" operations,
139 : : // false otherwise.
140 : : virtual int CanAdd() const;
141 : : virtual int CanDel() const;
142 : :
143 : : virtual void Add(Frame* f); // perform add operation
144 : : virtual void Delete(Frame* f); // perform delete operation
145 : :
146 : : // Return the expression converted to L-value form. If expr
147 : : // cannot be used as an L-value, reports an error and returns
148 : : // the current value of expr (this is the default method).
149 : : virtual Expr* MakeLvalue();
150 : :
151 : : // Marks the expression as one requiring (or at least appearing
152 : : // with) parentheses. Used for pretty-printing.
153 : 154 : void MarkParen() { paren = 1; }
154 : 0 : int IsParen() const { return paren; }
155 : :
156 : : const ListExpr* AsListExpr() const
157 : : {
158 : : CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
159 : : return (const ListExpr*) this;
160 : : }
161 : 3819 : ListExpr* AsListExpr()
162 : : {
163 [ - + ]: 3819 : CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
164 : 3819 : return (ListExpr*) this;
165 : : }
166 : :
167 : : void Describe(ODesc* d) const;
168 : :
169 : : bool Serialize(SerialInfo* info) const;
170 : : static Expr* Unserialize(UnserialInfo* info, BroExprTag want = EXPR_ANY);
171 : :
172 : : virtual TraversalCode Traverse(TraversalCallback* cb) const = 0;
173 : :
174 : : protected:
175 : 0 : Expr() { type = 0; }
176 : : Expr(BroExprTag arg_tag);
177 : :
178 : : virtual void ExprDescribe(ODesc* d) const = 0;
179 : : void AddTag(ODesc* d) const;
180 : :
181 : : // Puts the expression in canonical form.
182 : : virtual void Canonicize();
183 : :
184 : : void SetType(BroType* t);
185 : :
186 : : // Reports the given error and sets the expression's type to
187 : : // TYPE_ERROR.
188 : : void ExprError(const char msg[]);
189 : :
190 : : DECLARE_ABSTRACT_SERIAL(Expr);
191 : :
192 : : BroExprTag tag;
193 : : BroType* type;
194 : :
195 : : int paren;
196 : : };
197 : :
198 : : class NameExpr : public Expr {
199 : : public:
200 : : NameExpr(ID* id);
201 : : ~NameExpr();
202 : :
203 : 3455 : ID* Id() const { return id; }
204 : :
205 : : Expr* Simplify(SimplifyType simp_type);
206 : : Val* Eval(Frame* f) const;
207 : : void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
208 : : Expr* MakeLvalue();
209 : : int IsPure() const;
210 : :
211 : : TraversalCode Traverse(TraversalCallback* cb) const;
212 : :
213 : : protected:
214 : : friend class Expr;
215 : 0 : NameExpr() { id = 0; }
216 : :
217 : : void ReferenceID();
218 : : void ExprDescribe(ODesc* d) const;
219 : :
220 : 3 : DECLARE_SERIAL(NameExpr);
221 : :
222 : : ID* id;
223 : : };
224 : :
225 : : class ConstExpr : public Expr {
226 : : public:
227 : : ConstExpr(Val* val);
228 : : ~ConstExpr();
229 : :
230 : 352502 : Val* Value() const { return val; }
231 : :
232 : : Expr* Simplify(SimplifyType simp_type);
233 : : Val* Eval(Frame* f) const;
234 : :
235 : : TraversalCode Traverse(TraversalCallback* cb) const;
236 : :
237 : : protected:
238 : : friend class Expr;
239 : 0 : ConstExpr() { val = 0; }
240 : :
241 : : void ExprDescribe(ODesc* d) const;
242 : 12 : DECLARE_SERIAL(ConstExpr);
243 : :
244 : : Val* val;
245 : : };
246 : :
247 : : class UnaryExpr : public Expr {
248 : : public:
249 : 0 : Expr* Op() const { return op; }
250 : :
251 : : // Simplifies the operand and calls DoSimplify().
252 : : virtual Expr* Simplify(SimplifyType simp_type);
253 : :
254 : : // UnaryExpr::Eval correctly handles vector types. Any child
255 : : // class that overrides Eval() should be modified to handle
256 : : // vectors correctly as necessary.
257 : : Val* Eval(Frame* f) const;
258 : :
259 : : int IsPure() const;
260 : :
261 : : TraversalCode Traverse(TraversalCallback* cb) const;
262 : :
263 : : protected:
264 : : friend class Expr;
265 : 0 : UnaryExpr() { op = 0; }
266 : :
267 : : UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
268 : : virtual ~UnaryExpr();
269 : :
270 : : void ExprDescribe(ODesc* d) const;
271 : :
272 : : // Can be overridden by subclasses that want to take advantage
273 : : // of UnaryExpr's Simplify() method.
274 : : virtual Expr* DoSimplify();
275 : :
276 : : // Returns the expression folded using the given constant.
277 : : virtual Val* Fold(Val* v) const;
278 : :
279 : 0 : DECLARE_SERIAL(UnaryExpr);
280 : :
281 : : Expr* op;
282 : : };
283 : :
284 : : class BinaryExpr : public Expr {
285 : : public:
286 : 0 : Expr* Op1() const { return op1; }
287 : 0 : Expr* Op2() const { return op2; }
288 : :
289 : : // Simplifies both operands, folds them if constant,
290 : : // otherwise calls DoSimplify().
291 : : virtual Expr* Simplify(SimplifyType simp_type);
292 : : int IsPure() const;
293 : :
294 : : // BinaryExpr::Eval correctly handles vector types. Any child
295 : : // class that overrides Eval() should be modified to handle
296 : : // vectors correctly as necessary.
297 : : Val* Eval(Frame* f) const;
298 : :
299 : : TraversalCode Traverse(TraversalCallback* cb) const;
300 : :
301 : : protected:
302 : : friend class Expr;
303 : 0 : BinaryExpr() { op1 = op2 = 0; }
304 : :
305 : 7884 : BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
306 : 7884 : : Expr(arg_tag)
307 : : {
308 [ + - - + ]: 7884 : if ( ! (arg_op1 && arg_op2) )
309 : 0 : return;
310 : 7884 : op1 = arg_op1;
311 : 7884 : op2 = arg_op2;
312 [ + - ][ - + ]: 7884 : if ( op1->IsError() || op2->IsError() )
[ - + ]
313 : 7884 : SetError();
314 : 7884 : }
315 : : virtual ~BinaryExpr();
316 : :
317 : : // Can be overridden by subclasses that want to take advantage
318 : : // of BinaryExpr's Simplify() method.
319 : : virtual Expr* DoSimplify();
320 : :
321 : : // Returns the expression folded using the given constants.
322 : : virtual Val* Fold(Val* v1, Val* v2) const;
323 : :
324 : : // Same for when the constants are strings.
325 : : virtual Val* StringFold(Val* v1, Val* v2) const;
326 : :
327 : : // Same for when the constants are addresses or subnets.
328 : : virtual Val* AddrFold(Val* v1, Val* v2) const;
329 : : virtual Val* SubNetFold(Val* v1, Val* v2) const;
330 : :
331 [ # # ][ # # ]: 0 : int BothConst() const { return op1->IsConst() && op2->IsConst(); }
332 : :
333 : : // Simplify both operands and canonicize.
334 : : void SimplifyOps();
335 : :
336 : : // Exchange op1 and op2.
337 : : void SwapOps();
338 : :
339 : : // Promote the operands to the given type tag, if necessary.
340 : : void PromoteOps(TypeTag t);
341 : :
342 : : // Promote the expression to the given type tag (i.e., promote
343 : : // operands and also set expression's type).
344 : : void PromoteType(TypeTag t, bool is_vector);
345 : :
346 : : void ExprDescribe(ODesc* d) const;
347 : :
348 : 0 : DECLARE_SERIAL(BinaryExpr);
349 : :
350 : : Expr* op1;
351 : : Expr* op2;
352 : : };
353 : :
354 [ # # ][ # # ]: 0 : class CloneExpr : public UnaryExpr {
355 : : public:
356 : : CloneExpr(Expr* op);
357 : : Val* Eval(Frame* f) const;
358 : :
359 : : protected:
360 : : friend class Expr;
361 : 0 : CloneExpr() { }
362 : :
363 : : Val* Fold(Val* v) const;
364 : :
365 : 0 : DECLARE_SERIAL(CloneExpr);
366 : : };
367 : :
368 [ # # ][ # # ]: 0 : class IncrExpr : public UnaryExpr {
369 : : public:
370 : : IncrExpr(BroExprTag tag, Expr* op);
371 : :
372 : : Val* Eval(Frame* f) const;
373 : : Val* DoSingleEval(Frame* f, Val* v) const;
374 : : int IsPure() const;
375 : :
376 : : protected:
377 : : friend class Expr;
378 : 0 : IncrExpr() { }
379 : :
380 : 0 : DECLARE_SERIAL(IncrExpr);
381 : : };
382 : :
383 [ # # ][ # # ]: 0 : class NotExpr : public UnaryExpr {
384 : : public:
385 : : NotExpr(Expr* op);
386 : :
387 : : protected:
388 : : friend class Expr;
389 : 0 : NotExpr() { }
390 : :
391 : : Expr* DoSimplify();
392 : : Val* Fold(Val* v) const;
393 : :
394 : 0 : DECLARE_SERIAL(NotExpr);
395 : : };
396 : :
397 [ # # ][ # # ]: 0 : class PosExpr : public UnaryExpr {
398 : : public:
399 : : PosExpr(Expr* op);
400 : :
401 : : protected:
402 : : friend class Expr;
403 : 0 : PosExpr() { }
404 : :
405 : : Expr* DoSimplify();
406 : : Val* Fold(Val* v) const;
407 : :
408 : 0 : DECLARE_SERIAL(PosExpr);
409 : : };
410 : :
411 [ # # ][ # # ]: 0 : class NegExpr : public UnaryExpr {
412 : : public:
413 : : NegExpr(Expr* op);
414 : :
415 : : protected:
416 : : friend class Expr;
417 : 0 : NegExpr() { }
418 : :
419 : : Expr* DoSimplify();
420 : : Val* Fold(Val* v) const;
421 : :
422 : 0 : DECLARE_SERIAL(NegExpr);
423 : : };
424 : :
425 [ # # ][ # # ]: 0 : class SizeExpr : public UnaryExpr {
426 : : public:
427 : : SizeExpr(Expr* op);
428 : : Val* Eval(Frame* f) const;
429 : :
430 : : protected:
431 : : friend class Expr;
432 : 0 : SizeExpr() { }
433 : :
434 : : Val* Fold(Val* v) const;
435 : 0 : DECLARE_SERIAL(SizeExpr);
436 : : };
437 : :
438 [ # # ][ # # ]: 0 : class AddExpr : public BinaryExpr {
439 : : public:
440 : : AddExpr(Expr* op1, Expr* op2);
441 : : void Canonicize();
442 : :
443 : : protected:
444 : : friend class Expr;
445 : 0 : AddExpr() { }
446 : :
447 : : Expr* DoSimplify();
448 : :
449 : 0 : DECLARE_SERIAL(AddExpr);
450 : :
451 : : };
452 : :
453 [ # # ][ # # ]: 0 : class AddToExpr : public BinaryExpr {
454 : : public:
455 : : AddToExpr(Expr* op1, Expr* op2);
456 : : Val* Eval(Frame* f) const;
457 : :
458 : : protected:
459 : : friend class Expr;
460 : 0 : AddToExpr() { }
461 : :
462 : 0 : DECLARE_SERIAL(AddToExpr);
463 : : };
464 : :
465 [ # # ][ # # ]: 0 : class RemoveFromExpr : public BinaryExpr {
466 : : public:
467 : : RemoveFromExpr(Expr* op1, Expr* op2);
468 : : Val* Eval(Frame* f) const;
469 : :
470 : : protected:
471 : : friend class Expr;
472 : 0 : RemoveFromExpr() { }
473 : :
474 : 0 : DECLARE_SERIAL(RemoveFromExpr);
475 : : };
476 : :
477 [ # # ][ # # ]: 0 : class SubExpr : public BinaryExpr {
478 : : public:
479 : : SubExpr(Expr* op1, Expr* op2);
480 : :
481 : : protected:
482 : : friend class Expr;
483 : 0 : SubExpr() { }
484 : :
485 : : Expr* DoSimplify();
486 : :
487 : 0 : DECLARE_SERIAL(SubExpr);
488 : :
489 : : };
490 : :
491 [ # # ][ # # ]: 0 : class TimesExpr : public BinaryExpr {
492 : : public:
493 : : TimesExpr(Expr* op1, Expr* op2);
494 : : void Canonicize();
495 : :
496 : : protected:
497 : : friend class Expr;
498 : 0 : TimesExpr() { }
499 : :
500 : : Expr* DoSimplify();
501 : :
502 : 0 : DECLARE_SERIAL(TimesExpr);
503 : :
504 : : };
505 : :
506 [ # # ][ # # ]: 0 : class DivideExpr : public BinaryExpr {
507 : : public:
508 : : DivideExpr(Expr* op1, Expr* op2);
509 : :
510 : : protected:
511 : : friend class Expr;
512 : 0 : DivideExpr() { }
513 : :
514 : : Val* AddrFold(Val* v1, Val* v2) const;
515 : : Expr* DoSimplify();
516 : :
517 : 0 : DECLARE_SERIAL(DivideExpr);
518 : :
519 : : };
520 : :
521 [ # # ][ # # ]: 0 : class ModExpr : public BinaryExpr {
522 : : public:
523 : : ModExpr(Expr* op1, Expr* op2);
524 : :
525 : : protected:
526 : : friend class Expr;
527 : 0 : ModExpr() { }
528 : :
529 : : Expr* DoSimplify();
530 : :
531 : 0 : DECLARE_SERIAL(ModExpr);
532 : : };
533 : :
534 [ # # ][ # # ]: 0 : class BoolExpr : public BinaryExpr {
535 : : public:
536 : : BoolExpr(BroExprTag tag, Expr* op1, Expr* op2);
537 : :
538 : : Val* Eval(Frame* f) const;
539 : : Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const;
540 : :
541 : : protected:
542 : : friend class Expr;
543 : 0 : BoolExpr() { }
544 : :
545 : : Expr* DoSimplify();
546 : :
547 : 0 : DECLARE_SERIAL(BoolExpr);
548 : : };
549 : :
550 [ # # ][ # # ]: 0 : class EqExpr : public BinaryExpr {
551 : : public:
552 : : EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
553 : : void Canonicize();
554 : :
555 : : protected:
556 : : friend class Expr;
557 : 0 : EqExpr() { }
558 : :
559 : : Expr* DoSimplify();
560 : :
561 : : Val* Fold(Val* v1, Val* v2) const;
562 : :
563 : 0 : DECLARE_SERIAL(EqExpr);
564 : : };
565 : :
566 [ # # ][ # # ]: 0 : class RelExpr : public BinaryExpr {
567 : : public:
568 : : RelExpr(BroExprTag tag, Expr* op1, Expr* op2);
569 : : void Canonicize();
570 : :
571 : : protected:
572 : : friend class Expr;
573 : 0 : RelExpr() { }
574 : :
575 : : Expr* DoSimplify();
576 : :
577 : 0 : DECLARE_SERIAL(RelExpr);
578 : : };
579 : :
580 : : class CondExpr : public Expr {
581 : : public:
582 : : CondExpr(Expr* op1, Expr* op2, Expr* op3);
583 : : ~CondExpr();
584 : :
585 : : Expr* Simplify(SimplifyType simp_type);
586 : : Val* Eval(Frame* f) const;
587 : : int IsPure() const;
588 : :
589 : : TraversalCode Traverse(TraversalCallback* cb) const;
590 : :
591 : : protected:
592 : : friend class Expr;
593 : 0 : CondExpr() { op1 = op2 = op3 = 0; }
594 : :
595 : : void ExprDescribe(ODesc* d) const;
596 : :
597 : 0 : DECLARE_SERIAL(CondExpr);
598 : :
599 : : Expr* op1;
600 : : Expr* op2;
601 : : Expr* op3;
602 : : };
603 : :
604 [ # # ][ # # ]: 0 : class RefExpr : public UnaryExpr {
605 : : public:
606 : : RefExpr(Expr* op);
607 : :
608 : : void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
609 : : Expr* MakeLvalue();
610 : :
611 : : // Only overridden to avoid special vector handling which doesn't apply
612 : : // for this class.
613 : : Val* Eval(Val* v) const;
614 : :
615 : : protected:
616 : : friend class Expr;
617 : 0 : RefExpr() { }
618 : :
619 : 0 : DECLARE_SERIAL(RefExpr);
620 : : };
621 : :
622 : : class AssignExpr : public BinaryExpr {
623 : : public:
624 : : // If val is given, evaluating this expression will always yield the val
625 : : // yet still perform the assignment. Used for triggers.
626 : : AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0);
627 [ # # ][ # # ]: 0 : virtual ~AssignExpr() { Unref(val); }
628 : :
629 : : Expr* Simplify(SimplifyType simp_type);
630 : : Val* Eval(Frame* f) const;
631 : : void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const;
632 : : BroType* InitType() const;
633 : : int IsRecordElement(TypeDecl* td) const;
634 : : Val* InitVal(const BroType* t, Val* aggr) const;
635 : : int IsPure() const;
636 : :
637 : : protected:
638 : : friend class Expr;
639 : 0 : AssignExpr() { }
640 : :
641 : : bool TypeCheck();
642 : : bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
643 : :
644 : 0 : DECLARE_SERIAL(AssignExpr);
645 : :
646 : : int is_init;
647 : : Val* val; // optional
648 : : };
649 : :
650 [ # # ][ # # ]: 0 : class IndexExpr : public BinaryExpr {
651 : : public:
652 : : IndexExpr(Expr* op1, ListExpr* op2);
653 : :
654 : : int CanAdd() const;
655 : : int CanDel() const;
656 : :
657 : : void Add(Frame* f);
658 : : void Delete(Frame* f);
659 : :
660 : : Expr* Simplify(SimplifyType simp_type);
661 : : void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
662 : : Expr* MakeLvalue();
663 : :
664 : : // Need to override Eval since it can take a vector arg but does
665 : : // not necessarily return a vector.
666 : : Val* Eval(Frame* f) const;
667 : :
668 : : TraversalCode Traverse(TraversalCallback* cb) const;
669 : :
670 : : protected:
671 : : friend class Expr;
672 : 0 : IndexExpr() { }
673 : :
674 : : Val* Fold(Val* v1, Val* v2) const;
675 : :
676 : : void ExprDescribe(ODesc* d) const;
677 : :
678 : 0 : DECLARE_SERIAL(IndexExpr);
679 : : };
680 : :
681 : : class FieldExpr : public UnaryExpr {
682 : : public:
683 : : FieldExpr(Expr* op, const char* field_name);
684 : : ~FieldExpr();
685 : :
686 : 0 : int Field() const { return field; }
687 : :
688 : : Expr* Simplify(SimplifyType simp_type);
689 : : void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
690 : :
691 : : Expr* MakeLvalue();
692 : :
693 : : protected:
694 : : friend class Expr;
695 : 0 : FieldExpr() { field_name = 0; td = 0; }
696 : :
697 : : Val* Fold(Val* v) const;
698 : :
699 : : void ExprDescribe(ODesc* d) const;
700 : :
701 : 0 : DECLARE_SERIAL(FieldExpr);
702 : :
703 : : const char* field_name;
704 : : const TypeDecl* td;
705 : : int field; // -1 = attributes
706 : : };
707 : :
708 : : // "rec?$fieldname" is true if the value of $fieldname in rec is not nil.
709 : : // "rec?$$attrname" is true if the attribute attrname is not nil.
710 : : class HasFieldExpr : public UnaryExpr {
711 : : public:
712 : : HasFieldExpr(Expr* op, const char* field_name, bool is_attr);
713 : : ~HasFieldExpr();
714 : :
715 : : protected:
716 : : friend class Expr;
717 : 0 : HasFieldExpr() { field_name = 0; }
718 : :
719 : : Val* Fold(Val* v) const;
720 : :
721 : : void ExprDescribe(ODesc* d) const;
722 : :
723 : 0 : DECLARE_SERIAL(HasFieldExpr);
724 : :
725 : : bool is_attr;
726 : : const char* field_name;
727 : : int field;
728 : : };
729 : :
730 [ # # ][ # # ]: 0 : class RecordConstructorExpr : public UnaryExpr {
731 : : public:
732 : : RecordConstructorExpr(ListExpr* constructor_list);
733 : :
734 : : protected:
735 : : friend class Expr;
736 : 0 : RecordConstructorExpr() { }
737 : :
738 : : Val* InitVal(const BroType* t, Val* aggr) const;
739 : : Val* Fold(Val* v) const;
740 : :
741 : : void ExprDescribe(ODesc* d) const;
742 : :
743 : 0 : DECLARE_SERIAL(RecordConstructorExpr);
744 : : };
745 : :
746 : : class TableConstructorExpr : public UnaryExpr {
747 : : public:
748 : : TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
749 [ # # ][ # # ]: 0 : ~TableConstructorExpr() { Unref(attrs); }
750 : :
751 : : Val* Eval(Frame* f) const;
752 : :
753 : : protected:
754 : : friend class Expr;
755 : 0 : TableConstructorExpr() { }
756 : :
757 : : Val* InitVal(const BroType* t, Val* aggr) const;
758 : :
759 : : void ExprDescribe(ODesc* d) const;
760 : :
761 : 0 : DECLARE_SERIAL(TableConstructorExpr);
762 : :
763 : : Attributes* attrs;
764 : : };
765 : :
766 : : class SetConstructorExpr : public UnaryExpr {
767 : : public:
768 : : SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
769 [ # # ][ # # ]: 0 : ~SetConstructorExpr() { Unref(attrs); }
770 : :
771 : : Val* Eval(Frame* f) const;
772 : :
773 : : protected:
774 : : friend class Expr;
775 : 0 : SetConstructorExpr() { }
776 : :
777 : : Val* InitVal(const BroType* t, Val* aggr) const;
778 : :
779 : : void ExprDescribe(ODesc* d) const;
780 : :
781 : 0 : DECLARE_SERIAL(SetConstructorExpr);
782 : :
783 : : Attributes* attrs;
784 : : };
785 : :
786 [ # # ][ # # ]: 0 : class VectorConstructorExpr : public UnaryExpr {
787 : : public:
788 : : VectorConstructorExpr(ListExpr* constructor_list);
789 : :
790 : : Val* Eval(Frame* f) const;
791 : :
792 : : protected:
793 : : friend class Expr;
794 : 0 : VectorConstructorExpr() { }
795 : :
796 : : Val* InitVal(const BroType* t, Val* aggr) const;
797 : :
798 : : void ExprDescribe(ODesc* d) const;
799 : :
800 : 0 : DECLARE_SERIAL(VectorConstructorExpr);
801 : : };
802 : :
803 [ # # ][ # # ]: 0 : class FieldAssignExpr : public UnaryExpr {
804 : : public:
805 : : FieldAssignExpr(const char* field_name, Expr* value);
806 : :
807 : 952 : const char* FieldName() const { return field_name.c_str(); }
808 : :
809 : : void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const;
810 : : int IsRecordElement(TypeDecl* td) const;
811 : :
812 : : protected:
813 : : friend class Expr;
814 : 0 : FieldAssignExpr() { }
815 : :
816 : : void ExprDescribe(ODesc* d) const;
817 : :
818 : 0 : DECLARE_SERIAL(FieldAssignExpr);
819 : :
820 : : string field_name;
821 : : };
822 : :
823 [ # # ][ # # ]: 0 : class RecordMatchExpr : public BinaryExpr {
824 : : public:
825 : : RecordMatchExpr(Expr* op1 /* record to match */,
826 : : Expr* op2 /* cases to match against */);
827 : :
828 : : protected:
829 : : friend class Expr;
830 : 0 : RecordMatchExpr()
831 : 0 : {
832 : : pred_field_index = result_field_index =
833 : 0 : priority_field_index = 0;
834 : 0 : }
835 : :
836 : : virtual Val* Fold(Val* v1, Val* v2) const;
837 : : void ExprDescribe(ODesc*) const;
838 : :
839 : 0 : DECLARE_SERIAL(RecordMatchExpr);
840 : :
841 : : // The following are used to hold the field offset of
842 : : // $pred, $result, $priority, so the names only need to
843 : : // be looked up at compile-time.
844 : : int pred_field_index;
845 : : int result_field_index;
846 : : int priority_field_index;
847 : : };
848 : :
849 [ # # ][ # # ]: 0 : class ArithCoerceExpr : public UnaryExpr {
850 : : public:
851 : : ArithCoerceExpr(Expr* op, TypeTag t);
852 : :
853 : : protected:
854 : : friend class Expr;
855 : 0 : ArithCoerceExpr() { }
856 : :
857 : : Expr* DoSimplify();
858 : :
859 : : Val* FoldSingleVal(Val* v, InternalTypeTag t) const;
860 : : Val* Fold(Val* v) const;
861 : :
862 : 0 : DECLARE_SERIAL(ArithCoerceExpr);
863 : : };
864 : :
865 : : class RecordCoerceExpr : public UnaryExpr {
866 : : public:
867 : : RecordCoerceExpr(Expr* op, RecordType* r);
868 : : ~RecordCoerceExpr();
869 : :
870 : : protected:
871 : : friend class Expr;
872 : 0 : RecordCoerceExpr() { map = 0; }
873 : :
874 : : Val* Fold(Val* v) const;
875 : :
876 : 0 : DECLARE_SERIAL(RecordCoerceExpr);
877 : :
878 : : // For each super-record slot, gives subrecord slot with which to
879 : : // fill it.
880 : : int* map;
881 : : int map_size; // equivalent to Type()->AsRecordType()->NumFields()
882 : : };
883 : :
884 : : class TableCoerceExpr : public UnaryExpr {
885 : : public:
886 : : TableCoerceExpr(Expr* op, TableType* r);
887 : : ~TableCoerceExpr();
888 : :
889 : : protected:
890 : : friend class Expr;
891 : 0 : TableCoerceExpr() { }
892 : :
893 : : Val* Fold(Val* v) const;
894 : :
895 : 0 : DECLARE_SERIAL(TableCoerceExpr);
896 : : };
897 : :
898 : : // An internal operator for flattening array indices that are records
899 : : // into a list of individual values.
900 [ # # ][ # # ]: 0 : class FlattenExpr : public UnaryExpr {
901 : : public:
902 : : FlattenExpr(Expr* op);
903 : :
904 : : protected:
905 : : friend class Expr;
906 : 0 : FlattenExpr() { }
907 : :
908 : : Val* Fold(Val* v) const;
909 : :
910 : 0 : DECLARE_SERIAL(FlattenExpr);
911 : :
912 : : int num_fields;
913 : : };
914 : :
915 : : class EventHandler;
916 : :
917 : : class ScheduleTimer : public Timer {
918 : : public:
919 : : ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
920 : : TimerMgr* tmgr);
921 : : ~ScheduleTimer();
922 : :
923 : : void Dispatch(double t, int is_expire);
924 : :
925 : : protected:
926 : : EventHandlerPtr event;
927 : : val_list* args;
928 : : TimerMgr* tmgr;
929 : : };
930 : :
931 : : class ScheduleExpr : public Expr {
932 : : public:
933 : : ScheduleExpr(Expr* when, EventExpr* event);
934 : : ~ScheduleExpr();
935 : :
936 : : int IsPure() const;
937 : :
938 : : Expr* Simplify(SimplifyType simp_type);
939 : :
940 : : Val* Eval(Frame* f) const;
941 : :
942 : 0 : Expr* When() const { return when; }
943 : 0 : EventExpr* Event() const { return event; }
944 : :
945 : : TraversalCode Traverse(TraversalCallback* cb) const;
946 : :
947 : : protected:
948 : : friend class Expr;
949 : 0 : ScheduleExpr() { when = 0; event = 0; }
950 : :
951 : : void ExprDescribe(ODesc* d) const;
952 : :
953 : 0 : DECLARE_SERIAL(ScheduleExpr);
954 : :
955 : : Expr* when;
956 : : EventExpr* event;
957 : : };
958 : :
959 [ # # ][ # # ]: 0 : class InExpr : public BinaryExpr {
960 : : public:
961 : : InExpr(Expr* op1, Expr* op2);
962 : :
963 : : protected:
964 : : friend class Expr;
965 : 0 : InExpr() { }
966 : :
967 : : Val* Fold(Val* v1, Val* v2) const;
968 : :
969 : 0 : DECLARE_SERIAL(InExpr);
970 : :
971 : : };
972 : :
973 : : class CallExpr : public Expr {
974 : : public:
975 : : CallExpr(Expr* func, ListExpr* args);
976 : : ~CallExpr();
977 : :
978 : 0 : Expr* Func() const { return func; }
979 : 892 : ListExpr* Args() const { return args; }
980 : :
981 : : int IsPure() const;
982 : :
983 : : Expr* Simplify(SimplifyType simp_type);
984 : : Val* Eval(Frame* f) const;
985 : :
986 : : TraversalCode Traverse(TraversalCallback* cb) const;
987 : :
988 : : protected:
989 : : friend class Expr;
990 : 0 : CallExpr() { func = 0; args = 0; }
991 : :
992 : : void ExprDescribe(ODesc* d) const;
993 : :
994 : 0 : DECLARE_SERIAL(CallExpr);
995 : :
996 : : Expr* func;
997 : : ListExpr* args;
998 : : };
999 : :
1000 : : class EventExpr : public Expr {
1001 : : public:
1002 : : EventExpr(const char* name, ListExpr* args);
1003 : : ~EventExpr();
1004 : :
1005 : : const char* Name() const { return name.c_str(); }
1006 : 5065 : ListExpr* Args() const { return args; }
1007 : 5065 : EventHandlerPtr Handler() const { return handler; }
1008 : :
1009 : : Expr* Simplify(SimplifyType simp_type);
1010 : : Val* Eval(Frame* f) const;
1011 : :
1012 : : TraversalCode Traverse(TraversalCallback* cb) const;
1013 : :
1014 : : protected:
1015 : : friend class Expr;
1016 : 0 : EventExpr() { args = 0; }
1017 : :
1018 : : void ExprDescribe(ODesc* d) const;
1019 : :
1020 : 0 : DECLARE_SERIAL(EventExpr);
1021 : :
1022 : : string name;
1023 : : EventHandlerPtr handler;
1024 : : ListExpr* args;
1025 : : };
1026 : :
1027 : : class ListExpr : public Expr {
1028 : : public:
1029 : : ListExpr();
1030 : : ListExpr(Expr* e);
1031 : : ~ListExpr();
1032 : :
1033 : : void Append(Expr* e);
1034 : :
1035 : 212013 : const expr_list& Exprs() const { return exprs; }
1036 : 13856 : expr_list& Exprs() { return exprs; }
1037 : :
1038 : : // True if the entire list represents pure values.
1039 : : int IsPure() const;
1040 : :
1041 : : // True if the entire list represents constant values.
1042 : : int AllConst() const;
1043 : :
1044 : : Expr* Simplify(SimplifyType simp_type);
1045 : : Val* Eval(Frame* f) const;
1046 : :
1047 : : BroType* InitType() const;
1048 : : Val* InitVal(const BroType* t, Val* aggr) const;
1049 : : Expr* MakeLvalue();
1050 : : void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
1051 : :
1052 : : TraversalCode Traverse(TraversalCallback* cb) const;
1053 : :
1054 : : protected:
1055 : : Val* AddSetInit(const BroType* t, Val* aggr) const;
1056 : :
1057 : : void ExprDescribe(ODesc* d) const;
1058 : :
1059 : 0 : DECLARE_SERIAL(ListExpr);
1060 : :
1061 : : expr_list exprs;
1062 : : };
1063 : :
1064 : :
1065 [ # # ][ # # ]: 0 : class RecordAssignExpr : public ListExpr {
1066 : : public:
1067 : : RecordAssignExpr(Expr* record, Expr* init_list, int is_init);
1068 : :
1069 : 0 : Val* Eval(Frame* f) const { return ListExpr::Eval(f); }
1070 : :
1071 : : protected:
1072 : : friend class Expr;
1073 : 0 : RecordAssignExpr() { }
1074 : :
1075 : 0 : DECLARE_SERIAL(RecordAssignExpr);
1076 : : };
1077 : :
1078 : 234 : inline Val* Expr::ExprVal() const
1079 : : {
1080 [ - + ]: 234 : if ( ! IsConst() )
1081 : 0 : BadTag("ExprVal::Val", expr_name(tag), expr_name(EXPR_CONST));
1082 : 234 : return ((ConstExpr*) this)->Value();
1083 : : }
1084 : :
1085 : : // Decides whether to return an AssignExpr or a RecordAssignExpr.
1086 : : Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init);
1087 : :
1088 : : // Type-check the given expression(s) against the given type(s). Complain
1089 : : // if the expression cannot match the given type, returning 0. If it can
1090 : : // match, promote it as necessary (modifying the ref parameter accordingly)
1091 : : // and return 1.
1092 : : //
1093 : : // The second and third forms are for promoting a list of
1094 : : // expressions (which is updated in place) to either match a list of
1095 : : // types or a single type.
1096 : : //
1097 : : // Note, the type is not "const" because it can be ref'd.
1098 : : extern int check_and_promote_expr(Expr*& e, BroType* t);
1099 : : extern int check_and_promote_exprs(ListExpr*& elements, TypeList* types);
1100 : : extern int check_and_promote_exprs_to_type(ListExpr*& elements, BroType* type);
1101 : :
1102 : : // Returns a fully simplified form of the expression. Note that passed
1103 : : // expression and its subexpressions may be modified, Unref()'d, etc.
1104 : : Expr* simplify_expr(Expr* e, SimplifyType simp_type);
1105 : :
1106 : : // Returns a simplified ListExpr - guaranteed to still be a ListExpr,
1107 : : // even if it only contains one expr.
1108 : : ListExpr* simplify_expr_list(ListExpr* l, SimplifyType simp_type);
1109 : :
1110 : : // Returns a ListExpr simplified down to a list a values, or a nil
1111 : : // pointer if they couldn't all be reduced.
1112 : : val_list* eval_list(Frame* f, const ListExpr* l);
1113 : :
1114 : : // Returns true if two expressions are identical.
1115 : : extern int same_expr(const Expr* e1, const Expr* e2);
1116 : :
1117 : : // Returns true if e1 is "greater" than e2 - here "greater" is just
1118 : : // a heuristic, used with commutative operators to put them into
1119 : : // a canonical form.
1120 : : extern int expr_greater(const Expr* e1, const Expr* e2);
1121 : :
1122 : : // Return constants of the given type.
1123 : : Expr* make_zero(BroType* t);
1124 : : Expr* make_one(BroType* t);
1125 : :
1126 : : // True if the given Val* has a vector type
1127 : 166854 : inline bool is_vector(Expr* e) { return e->Type()->Tag() == TYPE_VECTOR; }
1128 : :
1129 : : #endif
|