File: TypeCompat.hh

package info (click to toggle)
eclipse-titan 6.1.0-1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 79,084 kB
  • ctags: 29,092
  • sloc: cpp: 210,764; ansic: 44,862; yacc: 21,034; sh: 12,594; makefile: 12,225; lex: 8,972; xml: 5,348; java: 4,849; perl: 3,780; python: 2,834; php: 175
file content (134 lines) | stat: -rw-r--r-- 5,668 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/******************************************************************************
 * Copyright (c) 2000-2016 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Balasko, Jeno
 *   Raduly, Csaba
 *
 ******************************************************************************/
#ifndef TYPECOMPAT_HH_
#define TYPECOMPAT_HH_

#include "string.hh"
#include "stack.hh"
#include "vector.hh"

struct expression_struct_t;

namespace Ttcn {
  class TemplateInstance;
}

namespace Common {
  class Module;
  class Type;
  class GovernedSimple;
  class Reference;

/** Compatibility information for error reporting during semantic checks and
 *  some helpers for code generation.  Used during semantic checks only.  */
class TypeCompatInfo {
private:
  Module *m_my_module;
  Type *m_type1;            /**< Type of the LHS. Not owned. */
  Type *m_type2;            /**< Type of the RHS. Not owned. */
  bool m_strict;            /**< Type compatibility means equivalence. */
  bool m_is_temp;           /**< Compatibility between templates. */
  bool m_needs_conversion;  /**< Need for conversion code generation. */
  bool m_erroneous;         /**< Set if type conversion is not possible. */
  string m_error_str;       /**< Additional information. */
  string m_ref_str1;        /**< Reference chain for the LHS.  */
  string m_ref_str2;        /**< Reference chain for the RHS.  */
  string subtype_error_str; /**< Subtype error string */
  bool str1_elem;           /**< LHS is a reference to a string element */
  bool str2_elem;           /**< RHS is a reference to a string element */
  /// Copy constructor disabled
  TypeCompatInfo(const TypeCompatInfo&);
  /// Assignment disabled
  TypeCompatInfo& operator=(const TypeCompatInfo&);
public:
  TypeCompatInfo(Module *p_my_module, Type *p_type1 = NULL,
                 Type *p_type2 = NULL, bool p_add_ref_str = true,
                 bool p_strict = true, bool p_is_temp = false);
  inline bool needs_conversion() const { return m_needs_conversion; }
  inline void set_needs_conversion(bool p_needs_conversion)
    { m_needs_conversion = p_needs_conversion; }
  void add_type_conversion(Type *p_from_type, Type *p_to_type);
  void append_ref_str(int p_ref_no, const string& p_ref);
  inline const string& get_ref_str(int p_ref_no)
    { return p_ref_no == 0 ? m_ref_str1 : m_ref_str2; }
  inline Type *get_type(int p_type_no) const
    { return p_type_no == 0 ? m_type1 : m_type2; }
  inline bool is_strict() const { return m_strict; }
  inline bool is_erroneous() const { return m_erroneous; }
  inline Module *get_my_module() const { return m_my_module; }
  void set_is_erroneous(Type *p_type1, Type *p_type2,
                        const string& p_error_str);
  inline const string& get_error_str() { return m_error_str; }
  /** Assemble the error message.  */
  string get_error_str_str() const;
  void set_subtype_error(const string error_str) { subtype_error_str = error_str; }
  bool is_subtype_error() const { return !subtype_error_str.empty(); }
  string get_subtype_error() { return subtype_error_str; }
  void set_str1_elem(bool p_str1_elem) { str1_elem = p_str1_elem; }
  void set_str2_elem(bool p_str2_elem) { str2_elem = p_str2_elem; }
  bool get_str1_elem() const { return str1_elem; }
  bool get_str2_elem() const { return str2_elem; }
};

class TypeConv {
private:
  Type *m_from;
  Type *m_to;
  bool m_is_temp;
public:
  TypeConv(Type *p_from, Type *p_to, bool p_is_temp) : m_from(p_from),
    m_to(p_to), m_is_temp(p_is_temp) { }
  inline Type *get_from_type() const { return m_from; }
  inline Type *get_to_type() const { return m_to; }
  inline bool is_temp() const { return m_is_temp; }
  /** Assemble the name of the generated conversion function.  Take care of
   *  types declared in other modules.  */
  static string get_conv_func(Type *p_from, Type *p_to, Module *p_mod);
  static bool needs_conv_refd(GovernedSimple *p_val_or_temp);
  /** Generate initial conversion code for a given value or template
   *  reference.  */
  static char *gen_conv_code_refd(char *str, const char *name,
                                  GovernedSimple *p_val_or_temp);
  void gen_conv_func(char **p_prototypes, char **p_bodies, Module *p_mod);
  void gen_conv_func_record_set(char **p_bodies, Module *p_mod);
  void gen_conv_func_array_record(char **p_bodies, Module *p_mod);
  void gen_conv_func_array_record_of(char **p_bodies, Module *p_mod);
  void gen_conv_func_record_set_record_of_set_of(char **p_bodies,
                                                 Module *p_mod);
  void gen_conv_func_choice_anytype(char **p_bodies, Module *p_mod);
};

/** Class to detect recursion in the type hierarchy.  It is used by
 *  is_compatible*() functions to check if the two types in question
 *  reference each other in a way that would cause problems (e.g. infinite
 *  recursion) during the semantic analysis.  */
class TypeChain {
private:
  vector<Type> m_chain;
  stack<int> m_marked_states;
  int m_first_double;
public:
  TypeChain();
  ~TypeChain();
  inline bool has_recursion() const { return m_first_double != -1; }
  /** Check if this is the first level of the type hierarchy.  The "root"
   *  types are always added at first and removed only by the
   *  destructor.  */
  inline bool empty() const { return m_chain.empty(); }
  void add(Type *p_type);
  void mark_state();
  void previous_state();
};

} /* namespace Common */
#endif /* TYPECOMPAT_HH_ */