Merge pull request #29 from BotondBaranyi/master
[deliverable/titan.core.git] / compiler2 / TypeCompat.hh
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Raduly, Csaba
11 *
12 ******************************************************************************/
13 #ifndef TYPECOMPAT_HH_
14 #define TYPECOMPAT_HH_
15
16 #include "string.hh"
17 #include "stack.hh"
18 #include "vector.hh"
19
20 struct expression_struct_t;
21
22 namespace Ttcn {
23 class TemplateInstance;
24 }
25
26 namespace Common {
27 class Module;
28 class Type;
29 class GovernedSimple;
30 class Reference;
31
32 /** Compatibility information for error reporting during semantic checks and
33 * some helpers for code generation. Used during semantic checks only. */
34 class TypeCompatInfo {
35 private:
36 Module *m_my_module;
37 Type *m_type1; /**< Type of the LHS. Not owned. */
38 Type *m_type2; /**< Type of the RHS. Not owned. */
39 bool m_strict; /**< Type compatibility means equivalence. */
40 bool m_is_temp; /**< Compatibility between templates. */
41 bool m_needs_conversion; /**< Need for conversion code generation. */
42 bool m_erroneous; /**< Set if type conversion is not possible. */
43 string m_error_str; /**< Additional information. */
44 string m_ref_str1; /**< Reference chain for the LHS. */
45 string m_ref_str2; /**< Reference chain for the RHS. */
46 string subtype_error_str; /**< Subtype error string */
47 bool str1_elem; /**< LHS is a reference to a string element */
48 bool str2_elem; /**< RHS is a reference to a string element */
49 /// Copy constructor disabled
50 TypeCompatInfo(const TypeCompatInfo&);
51 /// Assignment disabled
52 TypeCompatInfo& operator=(const TypeCompatInfo&);
53 public:
54 TypeCompatInfo(Module *p_my_module, Type *p_type1 = NULL,
55 Type *p_type2 = NULL, bool p_add_ref_str = true,
56 bool p_strict = true, bool p_is_temp = false);
57 inline bool needs_conversion() const { return m_needs_conversion; }
58 inline void set_needs_conversion(bool p_needs_conversion)
59 { m_needs_conversion = p_needs_conversion; }
60 void add_type_conversion(Type *p_from_type, Type *p_to_type);
61 void append_ref_str(int p_ref_no, const string& p_ref);
62 inline const string& get_ref_str(int p_ref_no)
63 { return p_ref_no == 0 ? m_ref_str1 : m_ref_str2; }
64 inline Type *get_type(int p_type_no) const
65 { return p_type_no == 0 ? m_type1 : m_type2; }
66 inline bool is_strict() const { return m_strict; }
67 inline bool is_erroneous() const { return m_erroneous; }
68 inline Module *get_my_module() const { return m_my_module; }
69 void set_is_erroneous(Type *p_type1, Type *p_type2,
70 const string& p_error_str);
71 inline const string& get_error_str() { return m_error_str; }
72 /** Assemble the error message. */
73 string get_error_str_str() const;
74 void set_subtype_error(const string error_str) { subtype_error_str = error_str; }
75 bool is_subtype_error() const { return !subtype_error_str.empty(); }
76 string get_subtype_error() { return subtype_error_str; }
77 void set_str1_elem(bool p_str1_elem) { str1_elem = p_str1_elem; }
78 void set_str2_elem(bool p_str2_elem) { str2_elem = p_str2_elem; }
79 bool get_str1_elem() const { return str1_elem; }
80 bool get_str2_elem() const { return str2_elem; }
81 };
82
83 class TypeConv {
84 private:
85 Type *m_from;
86 Type *m_to;
87 bool m_is_temp;
88 public:
89 TypeConv(Type *p_from, Type *p_to, bool p_is_temp) : m_from(p_from),
90 m_to(p_to), m_is_temp(p_is_temp) { }
91 inline Type *get_from_type() const { return m_from; }
92 inline Type *get_to_type() const { return m_to; }
93 inline bool is_temp() const { return m_is_temp; }
94 /** Assemble the name of the generated conversion function. Take care of
95 * types declared in other modules. */
96 static string get_conv_func(Type *p_from, Type *p_to, Module *p_mod);
97 static bool needs_conv_refd(GovernedSimple *p_val_or_temp);
98 static bool needs_conv_redir(Ttcn::TemplateInstance *p_ti, Reference *p_ref);
99 /** Generate initial conversion code for a given value or template
100 * reference. */
101 static char *gen_conv_code_refd(char *str, const char *name,
102 GovernedSimple *p_val_or_temp);
103 /** Generate conversion code for value redirect constructs. */
104 static void gen_conv_code_redir(struct expression_struct_t *expr,
105 Ttcn::TemplateInstance *p_ti,
106 Reference *p_ref);
107 void gen_conv_func(char **p_prototypes, char **p_bodies, Module *p_mod);
108 void gen_conv_func_record_set(char **p_bodies, Module *p_mod);
109 void gen_conv_func_array_record(char **p_bodies, Module *p_mod);
110 void gen_conv_func_array_record_of(char **p_bodies, Module *p_mod);
111 void gen_conv_func_record_set_record_of_set_of(char **p_bodies,
112 Module *p_mod);
113 void gen_conv_func_choice_anytype(char **p_bodies, Module *p_mod);
114 };
115
116 /** Class to detect recursion in the type hierarchy. It is used by
117 * is_compatible*() functions to check if the two types in question
118 * reference each other in a way that would cause problems (e.g. infinite
119 * recursion) during the semantic analysis. */
120 class TypeChain {
121 private:
122 vector<Type> m_chain;
123 stack<int> m_marked_states;
124 int m_first_double;
125 public:
126 TypeChain();
127 ~TypeChain();
128 inline bool has_recursion() const { return m_first_double != -1; }
129 /** Check if this is the first level of the type hierarchy. The "root"
130 * types are always added at first and removed only by the
131 * destructor. */
132 inline bool empty() const { return m_chain.empty(); }
133 void add(Type *p_type);
134 void mark_state();
135 void previous_state();
136 };
137
138 } /* namespace Common */
139 #endif /* TYPECOMPAT_HH_ */
This page took 0.03429 seconds and 5 git commands to generate.