Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 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 | #include "CompField.hh" | |
9 | #include "Type.hh" | |
10 | #include "Value.hh" | |
11 | #include "CompilerError.hh" | |
12 | ||
13 | namespace Common { | |
14 | ||
15 | // ================================= | |
16 | // ===== CompField | |
17 | // ================================= | |
18 | ||
19 | CompField::CompField(Identifier *p_name, Type *p_type, bool p_is_optional, | |
20 | Value *p_defval) | |
21 | : Node(), Location(), name(p_name), type(p_type), | |
22 | is_optional(p_is_optional), defval(p_defval), rawattrib(0) | |
23 | { | |
24 | if(!p_name || !p_type) | |
25 | FATAL_ERROR("NULL parameter: Common::CompField::CompField()"); | |
26 | type->set_ownertype(Type::OT_COMP_FIELD, this); | |
27 | } | |
28 | ||
29 | CompField::CompField(const CompField& p) | |
30 | : Node(p), Location(p), is_optional(p.is_optional), rawattrib(0) | |
31 | { | |
32 | name=p.name->clone(); | |
33 | type=p.type->clone(); | |
34 | type->set_ownertype(Type::OT_COMP_FIELD, this); | |
35 | defval=p.defval?p.defval->clone():0; | |
36 | } | |
37 | ||
38 | CompField::~CompField() | |
39 | { | |
40 | delete name; | |
41 | delete type; | |
42 | delete defval; | |
43 | delete rawattrib; | |
44 | } | |
45 | ||
46 | CompField *CompField::clone() const | |
47 | { | |
48 | return new CompField(*this); | |
49 | } | |
50 | ||
51 | void CompField::set_fullname(const string& p_fullname) | |
52 | { | |
53 | string base_name(p_fullname + "." + name->get_dispname()); | |
54 | Node::set_fullname(base_name); | |
55 | type->set_fullname(base_name); | |
56 | if (defval) defval->set_fullname(base_name + ".<defval>"); | |
57 | } | |
58 | ||
59 | void CompField::set_my_scope(Scope *p_scope) | |
60 | { | |
61 | type->set_my_scope(p_scope); | |
62 | if (defval) defval->set_my_scope(p_scope); | |
63 | } | |
64 | ||
65 | void CompField::set_raw_attrib(RawAST* r_attr) | |
66 | { | |
67 | delete rawattrib; | |
68 | rawattrib=r_attr; | |
69 | } | |
70 | ||
71 | void CompField::dump(unsigned level) const | |
72 | { | |
73 | name->dump(level); | |
74 | type->dump(level + 1); | |
75 | if(is_optional) | |
76 | DEBUG(level + 1, "optional"); | |
77 | if(defval) { | |
78 | DEBUG(level + 1, "with default value"); | |
79 | defval->dump(level + 2); | |
80 | } | |
81 | } | |
82 | ||
83 | // ================================= | |
84 | // ===== CompFieldMap | |
85 | // ================================= | |
86 | ||
87 | CompFieldMap::CompFieldMap(const CompFieldMap& p) | |
88 | : Node(p), my_type(0), checked(false) | |
89 | { | |
90 | size_t nof_comps = p.v.size(); | |
91 | for (size_t i = 0; i < nof_comps; i++) v.add(p.v[i]->clone()); | |
92 | } | |
93 | ||
94 | CompFieldMap::~CompFieldMap() | |
95 | { | |
96 | size_t nof_comps = v.size(); | |
97 | for (size_t i = 0; i < nof_comps; i++) delete v[i]; | |
98 | v.clear(); | |
99 | m.clear(); | |
100 | } | |
101 | ||
102 | CompFieldMap *CompFieldMap::clone() const | |
103 | { | |
104 | return new CompFieldMap(*this); | |
105 | } | |
106 | ||
107 | void CompFieldMap::set_fullname(const string& p_fullname) | |
108 | { | |
109 | Node::set_fullname(p_fullname); | |
110 | size_t nof_comps = v.size(); | |
111 | for (size_t i = 0; i < nof_comps; i++) v[i]->set_fullname(p_fullname); | |
112 | } | |
113 | ||
114 | void CompFieldMap::set_my_scope(Scope *p_scope) | |
115 | { | |
116 | size_t nof_comps = v.size(); | |
117 | for (size_t i = 0; i < nof_comps; i++) v[i]->set_my_scope(p_scope); | |
118 | } | |
119 | ||
120 | void CompFieldMap::add_comp(CompField *comp) | |
121 | { | |
122 | v.add(comp); | |
123 | if (checked) { | |
124 | const string& name = comp->get_name().get_name(); | |
125 | if (m.has_key(name)) FATAL_ERROR("CompFieldMap::add_comp(%s)", name.c_str()); | |
126 | m.add(name, comp); | |
127 | } | |
128 | } | |
129 | ||
130 | bool CompFieldMap::has_comp_withName(const Identifier& p_name) | |
131 | { | |
132 | if (!checked) chk_uniq(); | |
133 | return m.has_key(p_name.get_name()); | |
134 | } | |
135 | ||
136 | CompField* CompFieldMap::get_comp_byName(const Identifier& p_name) | |
137 | { | |
138 | if (!checked) chk_uniq(); | |
139 | return m[p_name.get_name()]; | |
140 | } | |
141 | ||
142 | const char *CompFieldMap::get_typetype_name() const | |
143 | { | |
144 | if (!my_type) FATAL_ERROR("CompFieldMap::get_typetype_name()"); | |
145 | switch (my_type->get_typetype()) { | |
146 | case Type::T_ANYTYPE: | |
147 | return "anytype"; | |
148 | case Type::T_CHOICE_T: | |
149 | return "union"; | |
150 | case Type::T_SEQ_T: | |
151 | return "record"; | |
152 | case Type::T_SET_T: | |
153 | return "set"; | |
154 | case Type::T_OPENTYPE: | |
155 | return "open type"; | |
156 | default: | |
157 | return "<unknown>"; | |
158 | } | |
159 | } | |
160 | ||
161 | void CompFieldMap::chk_uniq() | |
162 | { | |
163 | if (checked) return; | |
164 | const char *typetype_name = get_typetype_name(); | |
165 | size_t nof_comps = v.size(); | |
166 | for (size_t i = 0; i < nof_comps; i++) { | |
167 | CompField *comp = v[i]; | |
168 | const Identifier& id = comp->get_name(); | |
169 | const string& name = id.get_name(); | |
170 | if (m.has_key(name)) { | |
171 | const char *dispname = id.get_dispname().c_str(); | |
172 | comp->error("Duplicate %s field name `%s'", typetype_name, dispname); | |
173 | m[name]->note("Field `%s' is already defined here", dispname); | |
174 | } else m.add(name, comp); | |
175 | } | |
176 | checked = true; | |
177 | } | |
178 | ||
179 | void CompFieldMap::chk() | |
180 | { | |
181 | if (!checked) chk_uniq(); | |
182 | const char *typetype_name = get_typetype_name(); | |
183 | size_t nof_comps = v.size(); | |
184 | for (size_t i = 0; i < nof_comps; i++) { | |
185 | CompField *comp = v[i]; | |
186 | const Identifier& id = comp->get_name(); | |
187 | Error_Context cntxt(comp, "In %s field `%s'", typetype_name, | |
188 | id.get_dispname().c_str()); | |
189 | Type *t = comp->get_type(); | |
190 | t->set_genname(my_type->get_genname_own(), id.get_name()); | |
191 | t->set_parent_type(my_type); | |
192 | t->chk(); | |
193 | t->chk_embedded(true, "embedded into another type"); | |
194 | } | |
195 | } | |
196 | ||
197 | void CompFieldMap::dump(unsigned level) const | |
198 | { | |
199 | size_t nof_comps = v.size(); | |
200 | DEBUG(level, "component fields: (%lu pcs.) @ %p", | |
201 | (unsigned long) nof_comps, (const void*)this); | |
202 | for (size_t i = 0; i < nof_comps; i++) v[i]->dump(level + 1); | |
203 | } | |
204 | ||
205 | } /* namespace Common */ |