1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 ///////////////////////////////////////////////////////////////////////////////
15 struct expression_struct_t;
18 class TemplateInstance;
27 /** Compatibility information for error reporting during semantic checks and
28 * some helpers for code generation. Used during semantic checks only. */
29 class TypeCompatInfo {
32 Type *m_type1; /**< Type of the LHS. Not owned. */
33 Type *m_type2; /**< Type of the RHS. Not owned. */
34 bool m_strict; /**< Type compatibility means equivalence. */
35 bool m_is_temp; /**< Compatibility between templates. */
36 bool m_needs_conversion; /**< Need for conversion code generation. */
37 bool m_erroneous; /**< Set if type conversion is not possible. */
38 string m_error_str; /**< Additional information. */
39 string m_ref_str1; /**< Reference chain for the LHS. */
40 string m_ref_str2; /**< Reference chain for the RHS. */
41 string subtype_error_str; /**< Subtype error string */
42 bool str1_elem; /**< LHS is a reference to a string element */
43 bool str2_elem; /**< RHS is a reference to a string element */
44 /// Copy constructor disabled
45 TypeCompatInfo(const TypeCompatInfo&);
46 /// Assignment disabled
47 TypeCompatInfo& operator=(const TypeCompatInfo&);
49 TypeCompatInfo(Module *p_my_module, Type *p_type1 = NULL,
50 Type *p_type2 = NULL, bool p_add_ref_str = true,
51 bool p_strict = true, bool p_is_temp = false);
52 inline bool needs_conversion() const { return m_needs_conversion; }
53 inline void set_needs_conversion(bool p_needs_conversion)
54 { m_needs_conversion = p_needs_conversion; }
55 void add_type_conversion(Type *p_from_type, Type *p_to_type);
56 void append_ref_str(int p_ref_no, const string& p_ref);
57 inline const string& get_ref_str(int p_ref_no)
58 { return p_ref_no == 0 ? m_ref_str1 : m_ref_str2; }
59 inline Type *get_type(int p_type_no) const
60 { return p_type_no == 0 ? m_type1 : m_type2; }
61 inline bool is_strict() const { return m_strict; }
62 inline bool is_erroneous() const { return m_erroneous; }
63 inline Module *get_my_module() const { return m_my_module; }
64 void set_is_erroneous(Type *p_type1, Type *p_type2,
65 const string& p_error_str);
66 inline const string& get_error_str() { return m_error_str; }
67 /** Assemble the error message. */
68 string get_error_str_str() const;
69 void set_subtype_error(const string error_str) { subtype_error_str = error_str; }
70 bool is_subtype_error() const { return !subtype_error_str.empty(); }
71 string get_subtype_error() { return subtype_error_str; }
72 void set_str1_elem(bool p_str1_elem) { str1_elem = p_str1_elem; }
73 void set_str2_elem(bool p_str2_elem) { str2_elem = p_str2_elem; }
74 bool get_str1_elem() const { return str1_elem; }
75 bool get_str2_elem() const { return str2_elem; }
84 TypeConv(Type *p_from, Type *p_to, bool p_is_temp) : m_from(p_from),
85 m_to(p_to), m_is_temp(p_is_temp) { }
86 inline Type *get_from_type() const { return m_from; }
87 inline Type *get_to_type() const { return m_to; }
88 inline bool is_temp() const { return m_is_temp; }
89 /** Assemble the name of the generated conversion function. Take care of
90 * types declared in other modules. */
91 static string get_conv_func(Type *p_from, Type *p_to, Module *p_mod);
92 static bool needs_conv_refd(GovernedSimple *p_val_or_temp);
93 static bool needs_conv_redir(Ttcn::TemplateInstance *p_ti, Reference *p_ref);
94 /** Generate initial conversion code for a given value or template
96 static char *gen_conv_code_refd(char *str, const char *name,
97 GovernedSimple *p_val_or_temp);
98 /** Generate conversion code for value redirect constructs. */
99 static void gen_conv_code_redir(struct expression_struct_t *expr,
100 Ttcn::TemplateInstance *p_ti,
102 void gen_conv_func(char **p_prototypes, char **p_bodies, Module *p_mod);
103 void gen_conv_func_record_set(char **p_bodies, Module *p_mod);
104 void gen_conv_func_array_record(char **p_bodies, Module *p_mod);
105 void gen_conv_func_array_record_of(char **p_bodies, Module *p_mod);
106 void gen_conv_func_record_set_record_of_set_of(char **p_bodies,
108 void gen_conv_func_choice_anytype(char **p_bodies, Module *p_mod);
111 /** Class to detect recursion in the type hierarchy. It is used by
112 * is_compatible*() functions to check if the two types in question
113 * reference each other in a way that would cause problems (e.g. infinite
114 * recursion) during the semantic analysis. */
117 vector<Type> m_chain;
118 stack<int> m_marked_states;
123 inline bool has_recursion() const { return m_first_double != -1; }
124 /** Check if this is the first level of the type hierarchy. The "root"
125 * types are always added at first and removed only by the
127 inline bool empty() const { return m_chain.empty(); }
128 void add(Type *p_type);
130 void previous_state();
133 } /* namespace Common */
134 #endif /* TYPECOMPAT_HH_ */