1 #ifndef IVL_expression_H
2 #define IVL_expression_H
3 /*
4  * Copyright (c) 2011-2018 Stephen Williams (steve@icarus.com)
5  * Copyright CERN 2015 / Stephen Williams (steve@icarus.com),
6  * Copyright CERN 2016
7  * @author Maciej Suminski (maciej.suminski@cern.ch)
8  *
9  *    This source code is free software; you can redistribute it
10  *    and/or modify it in source code form under the terms of the GNU
11  *    General Public License as published by the Free Software
12  *    Foundation; either version 2 of the License, or (at your option)
13  *    any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 # include  "StringHeap.h"
26 # include  "LineInfo.h"
27 # include  "entity.h"
28 # include  <inttypes.h>
29 # include  <list>
30 # include  <memory>
31 # include  <vector>
32 # include  <cassert>
33 
34 class ExpRange;
35 class ScopeBase;
36 class SubprogramHeader;
37 class VType;
38 class VTypeArray;
39 class VTypePrimitive;
40 class ExpName;
41 
42 #if __cplusplus < 201103L
43 #define unique_ptr auto_ptr
44 #endif
45 
46 /*
47  * Helper class to recursively traverse an expression tree
48  * (i.e. complex expressions).
49  */
50 struct ExprVisitor {
ExprVisitorExprVisitor51     ExprVisitor() : level_(0) {}
~ExprVisitorExprVisitor52     virtual ~ExprVisitor() {}
53     virtual void operator() (Expression*s) = 0;
54 
55     // Methods to manage recursion depth. Every Expression::visit() method
56     // should call down() in the beginning and up() in the end.
downExprVisitor57     inline void down() { ++level_; }
upExprVisitor58     inline void up() { --level_; assert(level_ >= 0); }
59 
60 protected:
levelExprVisitor61     int level() const { return level_; }
62 
63 private:
64     int level_;
65 };
66 
67 /*
68  * The Expression class represents parsed expressions from the parsed
69  * VHDL input. The Expression class is a virtual class that holds more
70  * specific derived expression types.
71  */
72 class Expression : public LineInfo {
73 
74     public:
75       Expression();
76       virtual ~Expression() =0;
77 
78 	// Returns a deep copy of the expression.
79       virtual Expression*clone() const =0;
80 
81 	// This virtual method handles the special case of elaborating
82 	// an expression that is the l-value of a sequential variable
83 	// assignment. This generates an error for most cases, but
84 	// expressions that are valid l-values return 0 and set any
85 	// flags needed to indicate their status as writable variables.
86       virtual int elaborate_lval(Entity*ent, ScopeBase*scope,
87 				 bool is_sequ);
88 
89 	// This virtual method probes the expression to get the most
90 	// constrained type for the expression. For a given instance,
91 	// this may be called before the elaborate_expr method.
92       virtual const VType*probe_type(Entity*ent, ScopeBase*scope) const;
93 
94 	// The fit_type virtual method is used by the ExpConcat class
95 	// to probe the type of operands. The atype argument is the
96 	// type of the ExpConcat expression itself. This expression
97 	// returns its type as interpreted in this context. Really,
98 	// this is mostly about helping aggregate expressions within
99 	// concatenations to figure out their type.
100       virtual const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
101 
102 	// This virtual method elaborates an expression. The ltype is
103 	// the type of the lvalue expression, if known, and can be
104 	// used to calculate the type for the expression being
105 	// elaborated.
106       virtual int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
107 
108 	// Return the type that this expression would be if it were an
109 	// l-value. This should only be called after elaborate_lval is
110 	// called and only if elaborate_lval succeeded.
peek_type(void)111       inline const VType*peek_type(void) const { return type_; }
112 
113 	// This virtual method writes a VHDL-accurate representation
114 	// of this expression to the designated stream. This is used
115 	// for writing parsed types to library files.
116       virtual void write_to_stream(std::ostream&fd) const =0;
117 
118 	// The emit virtual method is called by architecture emit to
119 	// output the generated code for the expression. The derived
120 	// class fills in the details of what exactly happened.
121       virtual int emit(ostream&out, Entity*ent, ScopeBase*scope) const =0;
122 
123 	// The emit_package virtual message is similar, but is called
124 	// in a package context and to emit SV packages.
125       virtual int emit_package(std::ostream&out) const;
126 
127 	// The evaluate virtual method tries to evaluate expressions
128 	// to constant literal values. Return true and set the val
129 	// argument if the evaluation works, or return false if it
130 	// cannot be done.
evaluate(Entity *,ScopeBase *,int64_t &)131       virtual bool evaluate(Entity*, ScopeBase*, int64_t&) const { return false; }
evaluate(ScopeBase * scope,int64_t & val)132       bool evaluate(ScopeBase*scope, int64_t&val) const { return evaluate(NULL, scope, val); }
133 
134 	// The symbolic compare returns true if the two expressions
135 	// are equal without actually calculating the value.
136       virtual bool symbolic_compare(const Expression*that) const;
137 
138 	// This method returns true if the drawn Verilog for this
139 	// expression is a primary. A containing expression can use
140 	// this method to know if it needs to wrap parentheses. This
141 	// is somewhat optional, so it is better to return false if
142 	// not certain. The default implementation does return false.
143       virtual bool is_primary(void) const;
144 
145 	// Debug dump of the expression.
146       virtual void dump(ostream&out, int indent = 0) const =0;
147       virtual ostream& dump_inline(ostream&out) const;
148 
149 	// Recursively visits a tree of expressions (useful for complex expressions).
visit(ExprVisitor & func)150       virtual void visit(ExprVisitor& func) { func.down(); func(this); func.up(); }
151 
152     protected:
153 	// This function is called by the derived class during
154 	// elaboration to set the type of the current expression that
155 	// elaboration assigns to this expression.
156       void set_type(const VType*);
157 
158     private:
159       const VType*type_;
160 
161     private: // Not implemented
162       Expression(const Expression&);
163       Expression& operator = (const Expression&);
164 };
165 
166 /*
167  * Checks before cloning if the other expression actually exists (!=NULL).
168  */
safe_clone(const Expression * other)169 static inline Expression*safe_clone(const Expression*other) {
170       return (other ? other->clone() : NULL);
171 }
172 
FILE_NAME(Expression * tgt,const LineInfo * src)173 static inline void FILE_NAME(Expression*tgt, const LineInfo*src)
174 {
175       tgt->set_line(*src);
176 }
177 
178 static inline ostream& operator <<(ostream&out, const Expression&exp)
179 {
180       return exp.dump_inline(out);
181 }
182 
183 class ExpUnary : public Expression {
184 
185     public:
186       explicit ExpUnary(Expression*op1);
187       virtual ~ExpUnary() =0;
188 
peek_operand()189       inline const Expression*peek_operand() const { return operand1_; }
190 
191       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
192       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
193       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
194       void visit(ExprVisitor& func);
195 
196     protected:
write_to_stream_operand1(std::ostream & fd)197       inline void write_to_stream_operand1(std::ostream&fd) const
198       { operand1_->write_to_stream(fd); }
199 
200       int emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const;
201       void dump_operand1(ostream&out, int indent = 0) const;
202 
203     private:
204       Expression*operand1_;
205 };
206 
207 /*
208  * This is an abstract class that collects some of the common features
209  * of binary operators.
210  */
211 class ExpBinary : public Expression {
212 
213     public:
214       ExpBinary(Expression*op1, Expression*op2);
215       virtual ~ExpBinary() =0;
216 
peek_operand1(void)217       inline const Expression* peek_operand1(void) const { return operand1_; }
peek_operand2(void)218       inline const Expression* peek_operand2(void) const { return operand2_; }
219 
220       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
221       void visit(ExprVisitor& func);
222 
223     protected:
224 
225       int elaborate_exprs(Entity*, ScopeBase*, const VType*);
226       int emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const;
227       int emit_operand2(ostream&out, Entity*ent, ScopeBase*scope) const;
228 
229       bool eval_operand1(Entity*ent, ScopeBase*scope, int64_t&val) const;
230       bool eval_operand2(Entity*ent, ScopeBase*scope, int64_t&val) const;
231 
write_to_stream_operand1(std::ostream & out)232       inline void write_to_stream_operand1(std::ostream&out) const
233           { operand1_->write_to_stream(out); }
write_to_stream_operand2(std::ostream & out)234       inline void write_to_stream_operand2(std::ostream&out) const
235           { operand2_->write_to_stream(out); }
236 
237       void dump_operands(ostream&out, int indent = 0) const;
238 
239     private:
240       virtual const VType*resolve_operand_types_(const VType*t1, const VType*t2) const;
241 
242     private:
243       Expression*operand1_;
244       Expression*operand2_;
245 };
246 
247 class ExpAggregate : public Expression {
248 
249     public:
250 	// A "choice" is only part of an element. It is the thing that
251 	// is used to identify an element of the aggregate. It can
252 	// represent the index (or range) of an array, or the name of
253 	// a record member.
254       class choice_t {
255 	  public:
256 	      // Create an "others" choice
257 	    choice_t();
258 	      // Create a simple_expression choice
259 	    explicit choice_t(Expression*exp);
260 	      // Create a named choice
261 	    explicit choice_t(perm_string name);
262 	      // discreate_range choice
263 	    explicit choice_t(ExpRange*ran);
264 
265 	    choice_t(const choice_t&other);
266 
267 	    ~choice_t();
268 
269 	      // true if this represents an "others" choice
270 	    bool others() const;
271 	      // Return expression if this represents a simple_expression.
272 	    Expression*simple_expression(bool detach_flag =true);
273 	      // Return ExpRange if this represents a range_expression
274 	    ExpRange*range_expressions(void);
275 
276 	    void write_to_stream(std::ostream&fd);
277 	    void dump(ostream&out, int indent) const;
278 
279 	  private:
280 	    std::unique_ptr<Expression>expr_;
281 	    std::unique_ptr<ExpRange>  range_;
282 	  private: // not implemented
283 	    choice_t& operator= (const choice_t&);
284       };
285 
286       struct choice_element {
choice_elementchoice_element287 	    choice_element() : choice(), expr() {}
288 
choice_elementchoice_element289 	    choice_element(const choice_element&other) {
290 	        choice = other.choice ? new choice_t(*other.choice) : NULL;
291 	        expr = safe_clone(other.expr);
292 	    }
293 
294 	    choice_t*choice;
295 	    Expression*expr;
296 	    bool alias_flag;
297       };
298 
299 	// Elements are the syntactic items in an aggregate
300 	// expression. Each element expressions a bunch of fields
301 	// (choices) and binds them to a single expression
302       class element_t {
303 	  public:
304 	    explicit element_t(std::list<choice_t*>*fields, Expression*val);
305 	    element_t(const element_t&other);
306 	    ~element_t();
307 
count_choices()308 	    size_t count_choices() const { return fields_.size(); }
309 	    void map_choices(choice_element*dst);
310 
extract_expression()311 	    inline Expression* extract_expression() { return val_; }
312 	    void write_to_stream(std::ostream&fd) const;
313 
314 	    void dump(ostream&out, int indent) const;
315 
316 	  private:
317 	    std::vector<choice_t*>fields_;
318 	    Expression*val_;
319 	  private: // not implemented
320 	    element_t& operator = (const element_t&);
321       };
322 
323     public:
324       explicit ExpAggregate(std::list<element_t*>*el);
325       ~ExpAggregate();
326 
327       Expression*clone() const;
328 
329       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
330       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
331       void write_to_stream(std::ostream&fd) const;
332       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
333       void dump(ostream&out, int indent = 0) const;
334       void visit(ExprVisitor& func);
335 
336     private:
337       int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype);
338       int elaborate_expr_record_(Entity*ent, ScopeBase*scope, const VTypeRecord*ltype);
339       int emit_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*ltype) const;
340       int emit_record_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeRecord*ltype) const;
341 
342     private:
343 	// This is the elements as directly parsed.
344       std::vector<element_t*> elements_;
345 
346 	// These are the elements after elaboration. This form is
347 	// easier to check and emit.
348       std::vector<choice_element> aggregate_;
349 };
350 
351 class ExpArithmetic : public ExpBinary {
352 
353     public:
354       enum fun_t { PLUS, MINUS, MULT, DIV, MOD, REM, POW, xCONCAT };
355 
356     public:
357       ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2);
358       ~ExpArithmetic();
359 
clone()360       Expression*clone() const {
361           return new ExpArithmetic(fun_, peek_operand1()->clone(), peek_operand2()->clone());
362       }
363 
364       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
365       void write_to_stream(std::ostream&fd) const;
366       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
367       virtual bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
368       void dump(ostream&out, int indent = 0) const;
369 
370     private:
371       const VType* resolve_operand_types_(const VType*t1, const VType*t2) const;
372 
373     private:
374       fun_t fun_;
375 };
376 
377 class ExpAttribute : public Expression {
378 
379     public:
380       ExpAttribute(perm_string name,std::list<Expression*>*args);
381       virtual ~ExpAttribute();
382 
peek_attribute()383       inline perm_string peek_attribute() const { return name_; }
384 
385       // Constants for the standard attributes
386       static const perm_string LEFT;
387       static const perm_string RIGHT;
388 
389     protected:
390       std::list<Expression*>*clone_args() const;
391       int elaborate_args(Entity*ent, ScopeBase*scope, const VType*ltype);
392       void visit_args(ExprVisitor& func);
393 
394       bool evaluate_type_attr(const VType*type, Entity*ent, ScopeBase*scope, int64_t&val) const;
395       bool test_array_type(const VType*type) const;
396 
397       perm_string name_;
398       std::list<Expression*>*args_;
399 };
400 
401 class ExpObjAttribute : public ExpAttribute {
402     public:
403       ExpObjAttribute(ExpName*base, perm_string name, std::list<Expression*>*args);
404       ~ExpObjAttribute();
405 
406       Expression*clone() const;
407 
peek_base()408       inline const ExpName* peek_base() const { return base_; }
409 
410       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
411       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
412       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
413       void write_to_stream(std::ostream&fd) const;
414 	// Some attributes can be evaluated at compile time
415       bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
416       void dump(ostream&out, int indent = 0) const;
417       void visit(ExprVisitor& func);
418 
419     private:
420       ExpName*base_;
421 };
422 
423 class ExpTypeAttribute : public ExpAttribute {
424     public:
425       ExpTypeAttribute(const VType*base, perm_string name, std::list<Expression*>*args);
426       // no destructor - VType objects (base_) are shared between many expressions
427 
428       Expression*clone() const;
429 
peek_base()430       inline const VType* peek_base() const { return base_; }
431 
432       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
433       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
434       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
435       void write_to_stream(std::ostream&fd) const;
436 	// Some attributes can be evaluated at compile time
437       bool evaluate(ScopeBase*scope, int64_t&val) const;
438       bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
439       void dump(ostream&out, int indent = 0) const;
440       void visit(ExprVisitor& func);
441 
442     private:
443       const VType*base_;
444 };
445 
446 class ExpBitstring : public Expression {
447 
448     public:
449       explicit ExpBitstring(const char*);
ExpBitstring(const ExpBitstring & other)450       ExpBitstring(const ExpBitstring&other) : Expression() { value_ = other.value_; }
451       ~ExpBitstring();
452 
clone()453       Expression*clone() const { return new ExpBitstring(*this); }
454 
455       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
456       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
457       void write_to_stream(std::ostream&fd) const;
458       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
459       void dump(ostream&out, int indent = 0) const;
460 
461     private:
462       std::vector<char>value_;
463 };
464 
465 
466 class ExpCharacter : public Expression {
467 
468     public:
469       explicit ExpCharacter(char val);
ExpCharacter(const ExpCharacter & other)470       ExpCharacter(const ExpCharacter&other) : Expression() { value_ = other.value_; }
471       ~ExpCharacter();
472 
clone()473       Expression*clone() const { return new ExpCharacter(*this); }
474 
475       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
476       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
477       void write_to_stream(std::ostream&fd) const;
478       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
479       bool is_primary(void) const;
480       void dump(ostream&out, int indent = 0) const;
481 
value()482       char value() const { return value_; }
483 
484     private:
485       int emit_primitive_bit_(ostream&out, Entity*ent, ScopeBase*scope,
486 			      const VTypePrimitive*etype) const;
487 
488     private:
489       char value_;
490 };
491 
492 class ExpConcat : public Expression {
493 
494     public:
495       ExpConcat(Expression*op1, Expression*op2);
496       ~ExpConcat();
497 
clone()498       Expression*clone() const {
499           return new ExpConcat(operand1_->clone(), operand2_->clone());
500       }
501 
502       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
503       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
504       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
505       void write_to_stream(std::ostream&fd) const;
506       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
507       bool is_primary(void) const;
508       void dump(ostream&out, int indent = 0) const;
509       void visit(ExprVisitor& func);
510 
511     private:
512       int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype);
513 
514     private:
515       Expression*operand1_;
516       Expression*operand2_;
517 };
518 
519 /*
520  * The conditional expression represents the VHDL when-else
521  * expressions. Note that by the VHDL syntax rules, these cannot show
522  * up other than at the root of an expression.
523  */
524 class ExpConditional : public Expression {
525 
526     public:
527       class case_t : public LineInfo {
528 	  public:
529 	    case_t(Expression*cond, std::list<Expression*>*tru);
530 	    case_t(const case_t&other);
531 	    ~case_t();
532 
condition()533 	    inline Expression*condition() const { return cond_; }
set_condition(Expression * cond)534 	    inline void set_condition(Expression*cond) { cond_ = cond; }
true_clause()535 	    inline const std::list<Expression*>& true_clause() const { return true_clause_; }
536 
537 	    int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*lt);
538 	    int emit_option(ostream&out, Entity*ent, ScopeBase*scope) const;
539 	    int emit_default(ostream&out, Entity*ent, ScopeBase*scope) const;
540 	    void dump(ostream&out, int indent = 0) const;
extract_true_clause()541             std::list<Expression*>& extract_true_clause() { return true_clause_; }
542             void visit(ExprVisitor& func);
543 
544 	  private:
545 	    Expression*cond_;
546 	    std::list<Expression*> true_clause_;
547       };
548 
549     public:
550       ExpConditional(Expression*cond, std::list<Expression*>*tru,
551 		     std::list<case_t*>*options);
552       virtual ~ExpConditional();
553 
554       virtual Expression*clone() const;
555 
556       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
557       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
558       void write_to_stream(std::ostream&fd) const;
559       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
560       void dump(ostream&out, int indent = 0) const;
561       void visit(ExprVisitor& func);
562 
563     protected:
564       std::list<case_t*> options_;
565 };
566 
567 /*
568  * Expression to handle selected assignments (with .. select target <= value when ..)
569  */
570 class ExpSelected : public ExpConditional {
571     public:
572       ExpSelected(Expression*selector, std::list<case_t*>*options);
573       ~ExpSelected();
574 
575       Expression*clone() const;
576 
577     private:
578       Expression*selector_;
579 };
580 
581 /*
582  * This is a special expression type that represents posedge/negedge
583  * expressions in sensitivity lists.
584  */
585 class ExpEdge : public ExpUnary {
586 
587     public:
588       enum fun_t { NEGEDGE, ANYEDGE, POSEDGE };
589 
590     public:
591       explicit ExpEdge(ExpEdge::fun_t ty, Expression*op);
592       ~ExpEdge();
593 
clone()594       Expression*clone() const { return new ExpEdge(fun_, peek_operand()->clone()); }
595 
edge_fun()596       inline fun_t edge_fun() const { return fun_; }
597 
598       void write_to_stream(std::ostream&fd) const;
599       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
600       void dump(ostream&out, int indent = 0) const;
601 
602     private:
603       fun_t fun_;
604 };
605 
606 class ExpFunc : public Expression {
607 
608     public:
609       explicit ExpFunc(perm_string nn);
610       ExpFunc(perm_string nn, std::list<Expression*>*args);
611       ~ExpFunc();
612 
613       Expression*clone() const;
614 
615       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
func_name()616       inline perm_string func_name() const { return name_; }
func_args()617       inline size_t func_args() const { return argv_.size(); }
func_arg(size_t idx)618       inline const Expression*func_arg(size_t idx) const { return argv_[idx]; }
619       const VType*func_ret_type() const;
620 
621     public: // Base methods
622       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
623       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
624       void write_to_stream(std::ostream&fd) const;
625       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
626       void dump(ostream&out, int indent = 0) const;
627       void visit(ExprVisitor& func); // NOTE: does not handle expressions in subprogram body
628 
629       // Returns a subprogram header that matches the function call
630       SubprogramHeader*match_signature(Entity*ent, ScopeBase*scope) const;
631 
632     private:
633       perm_string name_;
634       std::vector<Expression*> argv_;
635       mutable SubprogramHeader*def_;
636 };
637 
638 class ExpInteger : public Expression {
639 
640     public:
641       explicit ExpInteger(int64_t val);
ExpInteger(const ExpInteger & other)642       ExpInteger(const ExpInteger&other) : Expression(), value_(other.value_) {}
643       ~ExpInteger();
644 
clone()645       Expression*clone() const { return new ExpInteger(*this); }
646 
647       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
648       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
649       void write_to_stream(std::ostream&fd) const;
650       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
651       int emit_package(std::ostream&out) const;
is_primary(void)652       bool is_primary(void) const { return true; }
653       bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
654       void dump(ostream&out, int indent = 0) const;
655       virtual ostream& dump_inline(ostream&out) const;
656 
657     private:
658       int64_t value_;
659 };
660 
661 class ExpReal : public Expression {
662 
663     public:
664       explicit ExpReal(double val);
ExpReal(const ExpReal & other)665       ExpReal(const ExpReal&other) : Expression(), value_(other.value_) {}
666       ~ExpReal();
667 
clone()668       Expression*clone() const { return new ExpReal(*this); }
669 
670       const VType*probe_type(Entity*ent, ScopeBase*scope) const;
671       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
672       void write_to_stream(std::ostream&fd) const;
673       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
674       int emit_package(std::ostream&out) const;
675       bool is_primary(void) const;
676       void dump(ostream&out, int indent = 0) const;
677       virtual ostream& dump_inline(ostream&out) const;
678 
679     private:
680       double value_;
681 };
682 
683 class ExpLogical : public ExpBinary {
684 
685     public:
686       enum fun_t { AND, OR, NAND, NOR, XOR, XNOR };
687 
688     public:
689       ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2);
690       ~ExpLogical();
691 
clone()692       Expression*clone() const {
693           return new ExpLogical(fun_, peek_operand1()->clone(), peek_operand2()->clone());
694       }
695 
logic_fun()696       inline fun_t logic_fun() const { return fun_; }
697 
698       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
699       void write_to_stream(std::ostream&fd) const;
700       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
701       void dump(ostream&out, int indent = 0) const;
702 
703     private:
704       fun_t fun_;
705 };
706 
707 /*
708  * The ExpName class represents an expression that is an identifier or
709  * other sort of name. The ExpNameALL is a special case of ExpName
710  * that represents the "all" keyword is contexts that can handle it.
711  */
712 class ExpName : public Expression {
713 
714     public:
715       explicit ExpName(perm_string nn);
716       ExpName(perm_string nn, std::list<Expression*>*indices);
717       ExpName(ExpName*prefix, perm_string nn, std::list<Expression*>*indices = NULL);
718       virtual ~ExpName();
719 
720     public: // Base methods
721       Expression*clone() const;
722       int elaborate_lval(Entity*ent, ScopeBase*scope, bool);
723       int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*);
724       const VType* probe_type(Entity*ent, ScopeBase*scope) const;
725       const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const;
726       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
727       void write_to_stream(std::ostream&fd) const;
728       int emit_indices(ostream&out, Entity*ent, ScopeBase*scope) const;
729       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
730       bool is_primary(void) const;
731       bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
732       bool symbolic_compare(const Expression*that) const;
733       void dump(ostream&out, int indent = 0) const;
name()734       inline const char* name() const { return name_; }
peek_name()735       inline const perm_string& peek_name() const { return name_; }
736       void add_index(std::list<Expression*>*idx);
737       void visit(ExprVisitor& func);
738 
739     private:
740       class index_t {
741       public:
742           index_t(Expression*idx, Expression*size, Expression*offset = NULL) :
idx_(idx)743             idx_(idx), size_(size), offset_(offset) {}
~index_t()744           ~index_t() {
745                 delete idx_;
746                 delete size_;
747                 delete offset_;
748           }
749 
750           int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
751 
752       private:
753           Expression*idx_;
754           Expression*size_;
755           Expression*offset_;
756       };
757 
758       const VType* elaborate_adjust_type_with_range_(Entity*ent, ScopeBase*scope, const VType*type);
759 
760       int elaborate_lval_(Entity*ent, ScopeBase*scope, bool, ExpName*suffix);
761       const VType* probe_prefix_type_(Entity*ent, ScopeBase*scope) const;
762       const VType* probe_prefixed_type_(Entity*ent, ScopeBase*scope) const;
763 
764       int emit_as_prefix_(ostream&out, Entity*ent, ScopeBase*scope) const;
765 
766 	// There are some workarounds required for constant arrays/records, as
767 	// they are currently emitted as flat localparams (without any type
768 	// information). The following workarounds adjust the access indices
769 	// to select appropriate parts of the localparam.
770       bool try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
771                             list<index_t*>&indices, int&data_size) const;
772 
773       bool check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope,
774                                          list<index_t*>&indices, int&data_size) const;
775 
776       bool check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope,
777                                           list<index_t*>&indices, int&data_size) const;
778 
779       int emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope,
780                            const list<index_t*>&indices, int field_size) const;
781 
782     private:
783       Expression*index(unsigned int number) const;
784 
785       std::unique_ptr<ExpName> prefix_;
786       perm_string name_;
787       std::list<Expression*>*indices_;
788 };
789 
790 class ExpNameALL : public ExpName {
791 
792     public:
ExpNameALL()793       ExpNameALL() : ExpName(empty_perm_string) { }
794 
795     public:
796       const VType* probe_type(Entity*ent, ScopeBase*scope) const;
797       void dump(ostream&out, int indent =0) const;
798 };
799 
800 class ExpRelation : public ExpBinary {
801 
802     public:
803       enum fun_t { EQ, LT, GT, NEQ, LE, GE };
804 
relation_fun(void)805       inline fun_t relation_fun(void) const { return fun_; }
806 
807     public:
808       ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2);
809       ~ExpRelation();
810 
clone()811       Expression*clone() const {
812           return new ExpRelation(fun_, peek_operand1()->clone(), peek_operand2()->clone());
813       }
814 
815       const VType* probe_type(Entity*ent, ScopeBase*scope) const;
816       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
817       void write_to_stream(std::ostream&fd) const;
818       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
819       void dump(ostream&out, int indent = 0) const;
820 
821     private:
822       fun_t fun_;
823 };
824 
825 /*
826  * Helper class to handle name expressions coming from another scope. As such,
827  * we get more information regarding their type, etc. from the associated scope.
828  */
829 class ExpScopedName : public Expression {
830     public:
831         ExpScopedName(perm_string scope, ExpName*exp);
832         ~ExpScopedName();
833 
clone()834         Expression*clone() const
835         { return new ExpScopedName(scope_name_, static_cast<ExpName*>(name_->clone())); }
836 
elaborate_lval(Entity * ent,ScopeBase * scope,bool is_sequ)837         int elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ)
838         { return name_->elaborate_lval(ent, get_scope(scope), is_sequ); }
839 
elaborate_rval(Entity * ent,ScopeBase * scope,const InterfacePort * lval)840         int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lval)
841         { return name_->elaborate_rval(ent, get_scope(scope), lval); }
842 
probe_type(Entity * ent,ScopeBase * scope)843         const VType* probe_type(Entity*ent, ScopeBase*scope) const
844         { return name_->probe_type(ent, get_scope(scope)); }
845 
fit_type(Entity * ent,ScopeBase * scope,const VTypeArray * host)846         const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const
847         { return name_->fit_type(ent, get_scope(scope), host); }
848 
elaborate_expr(Entity * ent,ScopeBase * scope,const VType * ltype)849         int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
850         { return name_->elaborate_expr(ent, get_scope(scope), ltype); }
851 
write_to_stream(std::ostream & fd)852         void write_to_stream(std::ostream&fd) const
853         { name_->write_to_stream(fd); }
854 
emit(ostream & out,Entity * ent,ScopeBase * scope)855         int emit(ostream&out, Entity*ent, ScopeBase*scope) const {
856             out << scope_name_ << ".";
857             return name_->emit(out, ent, scope);
858         }
859 
is_primary(void)860         bool is_primary(void) const
861         { return name_->is_primary(); }
862 
evaluate(Entity * ent,ScopeBase *,int64_t & val)863         bool evaluate(Entity*ent, ScopeBase*, int64_t&val) const
864         { return name_->evaluate(ent, scope_, val); }
865 
symbolic_compare(const Expression * that)866         bool symbolic_compare(const Expression*that) const
867         { return name_->symbolic_compare(that); }
868 
869         void dump(ostream&out, int indent = 0) const;
870 
871         void visit(ExprVisitor&func);
872 
873     private:
874         // Functions that resolve the origin scope for the name expression
875         ScopeBase*get_scope(const ScopeBase*scope);
876         ScopeBase*get_scope(const ScopeBase*scope) const;
877 
878         perm_string scope_name_;
879         ScopeBase*scope_;
880         ExpName*name_;
881 };
882 
883 class ExpShift : public ExpBinary {
884     public:
885       enum shift_t { SRL, SLL, SRA, SLA, ROL, ROR };
886 
887     public:
888       ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2);
889 
clone()890       Expression*clone() const {
891           return new ExpShift(shift_, peek_operand1()->clone(), peek_operand2()->clone());
892       }
893 
894       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
895       void write_to_stream(std::ostream&fd) const;
896       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
897       bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
898       void dump(ostream&out, int indent = 0) const;
899 
900     private:
901       shift_t shift_;
902 };
903 
904 class ExpString : public Expression {
905 
906     public:
907       explicit ExpString(const char*);
ExpString(const ExpString & other)908       ExpString(const ExpString&other) : Expression(), value_(other.value_) {}
909       ~ExpString();
910 
clone()911       Expression*clone() const { return new ExpString(*this); }
912 
913       const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
914       int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
915       void write_to_stream(std::ostream&fd) const;
916       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
917       bool is_primary(void) const;
918       void dump(ostream&out, int indent = 0) const;
get_value()919       const std::string& get_value() const { return value_; }
920 
921 	// Converts quotation marks (") to its escaped
922 	// counterpart in SystemVerilog (\")
923       static std::string escape_quot(const std::string& str);
924 
925     private:
926       int emit_as_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*arr) const;
927 
928     private:
929       std::string value_;
930 };
931 
932 class ExpUAbs : public ExpUnary {
933 
934     public:
935       explicit ExpUAbs(Expression*op1);
936       ~ExpUAbs();
937 
clone()938       Expression*clone() const { return new ExpUAbs(peek_operand()->clone()); }
939 
940       void write_to_stream(std::ostream&fd) const;
941       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
942       void dump(ostream&out, int indent = 0) const;
943 };
944 
945 class ExpUNot : public ExpUnary {
946 
947     public:
948       explicit ExpUNot(Expression*op1);
949       ~ExpUNot();
950 
clone()951       Expression*clone() const { return new ExpUNot(peek_operand()->clone()); }
952 
953       void write_to_stream(std::ostream&fd) const;
954       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
955       void dump(ostream&out, int indent = 0) const;
956 };
957 
958 class ExpUMinus : public ExpUnary {
959 
960     public:
961       explicit ExpUMinus(Expression*op1);
962       ~ExpUMinus();
963 
clone()964       Expression*clone() const { return new ExpUMinus(peek_operand()->clone()); }
965 
966       void write_to_stream(std::ostream&fd) const;
967       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
968       void dump(ostream&out, int indent = 0) const;
969 };
970 
971 /*
972  * Class that wraps other expressions to cast them to other types.
973  */
974 class ExpCast : public Expression {
975 
976     public:
977       ExpCast(Expression*base, const VType*type);
978       ~ExpCast();
979 
clone()980       Expression*clone() const { return new ExpCast(base_->clone(), type_->clone()); }
981 
elaborate_expr(Entity * ent,ScopeBase * scope,const VType *)982       inline int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*) {
983             return base_->elaborate_expr(ent, scope, type_);
984       }
985       void write_to_stream(std::ostream&fd) const;
986       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
987       void dump(ostream&out, int indent = 0) const;
988       void visit(ExprVisitor& func);
989 
990     private:
991       Expression*base_;
992       const VType*type_;
993 };
994 
995 /*
996  * Class that handles 'new' statement. VHDL is not capable of dynamic memory
997  * allocation, but it is useful for emitting some cases.
998  */
999 class ExpNew : public Expression {
1000 
1001     public:
1002       explicit ExpNew(Expression*size);
1003       ~ExpNew();
1004 
clone()1005       Expression*clone() const { return new ExpNew(size_->clone()); }
1006 
1007       // There is no 'new' in VHDL - do not emit anything
write_to_stream(std::ostream &)1008       void write_to_stream(std::ostream&) const {};
1009       int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1010       void dump(ostream&out, int indent = 0) const;
1011       void visit(ExprVisitor& func);
1012 
1013     private:
1014       Expression*size_;
1015 };
1016 
1017 class ExpTime : public Expression {
1018     public:
1019         typedef enum { FS, PS, NS, US, MS, S } timeunit_t;
1020 
1021         ExpTime(uint64_t amount, timeunit_t unit);
1022 
clone()1023         Expression*clone() const { return new ExpTime(amount_, unit_); }
1024 
1025         int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
1026         void write_to_stream(std::ostream&) const;
1027         int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1028         //bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
1029         void dump(ostream&out, int indent = 0) const;
1030 
1031     private:
1032         // Returns the time value expressed in femtoseconds
1033         double to_fs() const;
1034         uint64_t amount_;
1035         timeunit_t unit_;
1036 };
1037 
1038 class ExpRange : public Expression {
1039     public:
1040         typedef enum { DOWNTO, TO, AUTO } range_dir_t;
1041 
1042         // Regular range
1043         ExpRange(Expression*left_idx, Expression*right_idx, range_dir_t dir);
1044         // 'range/'reverse range attribute
1045         ExpRange(ExpName*base, bool reverse_range);
1046         ~ExpRange();
1047 
1048         Expression*clone() const;
1049 
1050         // Returns the upper boundary
1051         Expression*msb();
1052         // Returns the lower boundary
1053         Expression*lsb();
1054 
1055         Expression*left();
1056         Expression*right();
1057 
direction()1058         range_dir_t direction() const { return direction_; }
1059 
1060         int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
1061         void write_to_stream(std::ostream&) const;
1062         int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1063         void dump(ostream&out, int indent = 0) const;
1064     private:
1065         // Regular range related fields
1066         Expression*left_, *right_;
1067         range_dir_t direction_;
1068 
1069         // 'range/'reverse_range attribute related fields
1070         // Flag to indicate it is a 'range/'reverse_range expression
1071         bool range_expr_;
1072         // Object name to which the attribute is applied
1073         ExpName*range_base_;
1074         // Flag to distinguish between 'range & 'reverse_range
1075         bool range_reverse_;
1076 };
1077 
1078 // Helper class that wraps other expression to specify delay.
1079 class ExpDelay : public Expression {
1080 public:
1081     ExpDelay(Expression*expr, Expression*delay);
1082     ~ExpDelay();
1083 
clone()1084     Expression*clone() const { return new ExpDelay(expr_->clone(), delay_->clone()); }
1085 
1086     int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
1087     void write_to_stream(std::ostream&) const;
1088     int emit(ostream&out, Entity*ent, ScopeBase*scope) const;
1089     void dump(ostream&out, int indent = 0) const;
1090     void visit(ExprVisitor& func);
1091 
peek_expr()1092     const Expression*peek_expr() const { return expr_; }
peek_delay()1093     const Expression*peek_delay() const { return delay_; }
1094 
1095 private:
1096     Expression*expr_;
1097     Expression*delay_;
1098 };
1099 
1100 #if __cplusplus < 201103L
1101 #undef unique_ptr
1102 #endif
1103 
1104 #endif /* IVL_expression_H */
1105