OpenASIP 2.2
Loading...
Searching...
No Matches
Scope.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file Scope.cc
26 *
27 * Implementation of Scope class.
28 *
29 * @author Ari Metsähalme 2005 (ari.metsahalme-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include "Scope.hh"
34#include "CodeLabel.hh"
35#include "DataLabel.hh"
36#include "ContainerTools.hh"
37#include "Application.hh"
38
39namespace TTAProgram {
40
41/////////////////////////////////////////////////////////////////////////////
42// Scope
43/////////////////////////////////////////////////////////////////////////////
44
45/**
46 * Constructor.
47 */
48Scope::Scope(): parent_(NULL) {
49}
50
51/**
52 * Destructor.
53 */
55 for (unsigned int i = 0; i < dataLabels_.size(); i++) {
56 delete dataLabels_.at(i);
57 }
58 dataLabels_.clear();
59
60 for (unsigned int i = 0; i < codeLabels_.size(); i++) {
61 delete codeLabels_.at(i);
62 }
63 codeLabels_.clear();
64}
65
66/**
67 * Tells whether this is a global scope.
68 *
69 * @return True if this is a global scope.
70 */
71bool
73 return false;
74}
75
76/**
77 * Tells whether this is a unit scope.
78 *
79 * @return True if this is a unit scope.
80 */
81bool
83 return false;
84}
85
86/**
87 * Tells whether this is a procedure scope.
88 *
89 * @return True if this is a procedure scope.
90 */
91bool
93 return false;
94}
95
96/**
97 * Tells whether this is a local scope.
98 *
99 * @return True if this is a local scope.
100 */
101bool
103 return false;
104}
105
106/**
107 * Adds a child scope to this scope.
108 *
109 * @param scope The child scope to be added.
110 * @exception ObjectAlreadyExists if the given scope has already been added.
111 * or a scope with the same name already exists.
112 */
113void
114Scope::addChild(const Scope& scope) {
116 children_.push_back(&scope);
117 } else {
118 throw ObjectAlreadyExists(__FILE__, __LINE__);
119 }
120}
121
122/**
123 * Return the parent scope., that is, the scope that contains this scope.
124 *
125 * @return The parent scope, that is, the scope that contains this scope.
126 * @exception WrongSubclass if this scope has no parent scope (it is the
127 * global scope).
128 * @exception IllegalRegistration if no parent has been set (and the scope
129 * is not the global scope.
130 */
131Scope&
133 if (isGlobal()) {
134 throw WrongSubclass(
135 __FILE__, __LINE__, "Scope::parent()",
136 "Global scope cannot have parent scope.");
137 } else if (parent_ == NULL) {
139 __FILE__, __LINE__, "Scope::parent()", "No parent set.");
140 } else {
141 return *parent_;
142 }
143}
144
145/**
146 * Sets the parent scope.
147 *
148 * @param scope The new parent scope.
149 * @exception WrongSubclass if the scope is the global scope.
150 */
151void
153 if (!isGlobal()) {
154 parent_ = &scope;
155 } else {
156 throw WrongSubclass(
157 __FILE__, __LINE__, "Scope::parent()",
158 "Global scope cannot have parent scope.");
159 }
160}
161
162/**
163 * Returns the number of contained scopes.
164 *
165 * Only scopes directly contained in this scope are counted, not inner
166 * scopes inside one of the child scopes.
167 *
168 * @return The number of contained scopes.
169 */
170int
172 return children_.size();
173}
174
175/**
176 * Returns the child scope at given index.
177 *
178 * @param index The index of the child scope.
179 * @return The child scope at given index.
180 * @exception OutOfRange if the exceeds the number of scopes contained in
181 * this scope.
182 */
183const Scope&
184Scope::child(int index) const {
185 if (index >= 0 && static_cast<unsigned int>(index) < children_.size()) {
186 return *children_.at(index);
187 } else {
188 throw OutOfRange(__FILE__, __LINE__);
189 }
190}
191
192/**
193 * Tells whether this scope contains a code label with the given name.
194 *
195 * @param The name of the label.
196 * @return True if this scope contains a code label with the given name.
197 */
198bool
199Scope::containsCodeLabel(const std::string& name) const {
200 for (unsigned int i = 0; i < codeLabels_.size(); i++) {
201 if (name == codeLabels_.at(i)->name()) {
202 return true;
203 }
204 }
205 return false;
206}
207
208/**
209 * Tells whether this scope contains a data label with the given name.
210 *
211 * @param The name of the label.
212 * @return True if this scope contains a data label with the given name.
213 */
214bool
215Scope::containsDataLabel(const std::string& name) const {
216 for (unsigned int i = 0; i < dataLabels_.size(); i++) {
217 if (name == dataLabels_.at(i)->name()) {
218 return true;
219 }
220 }
221 return false;
222}
223
224/**
225 * Returns the code label with the given name.
226 *
227 * @param name The name of the label.
228 * @exception KeyNotFound if no code label with the given name exists in this
229 * scope.
230 * @return The code label with the given name.
231 */
232const CodeLabel&
233Scope::codeLabel(const std::string& name) const {
234 for (unsigned int i = 0; i < codeLabels_.size(); i++) {
235 if (name == codeLabels_.at(i)->name()) {
236 return *codeLabels_.at(i);
237 }
238 }
239 throw KeyNotFound(__FILE__, __LINE__);
240}
241
242/**
243 * Returns the data label with the given name.
244 *
245 * @param name The name of the label.
246 * @exception KeyNotFound if no data label with the given name exists in this
247 * scope.
248 * @return The data label with the given name.
249 */
250const DataLabel&
251Scope::dataLabel(const std::string& name) const {
252 for (unsigned int i = 0; i < dataLabels_.size(); i++) {
253 if (name == dataLabels_.at(i)->name()) {
254 return *dataLabels_.at(i);
255 }
256 }
257 throw KeyNotFound(__FILE__, __LINE__);
258}
259
260/**
261 * Returns the number of code labels in the given address visible in this
262 * scope.
263 *
264 * @param address The address of the label.
265 * @return The number of code labels in the given address visible in this
266 * scope.
267 */
268int
270 int count = 0;
271 for (unsigned int i = 0; i < codeLabels_.size(); i++) {
272 if (&codeLabels_.at(i)->address().space() == &address.space() &&
273 codeLabels_.at(i)->address().location() == address.location()) {
274 count++;
275 }
276 }
277 return count;
278}
279
280/**
281 * Returns a code label visible in this scope in the given address and index.
282 *
283 * @param address The address of the code label.
284 * @param index The index of the label if there area many labels at this
285 * address.
286 * @return A code label visible in this scope in the given address and index.
287 */
288const CodeLabel&
289Scope::codeLabel(Address address, int index) const {
290 if (index < codeLabelCount(address)) {
291
292 int found = -1;
293 for (unsigned int i = 0; i < codeLabels_.size(); i++) {
294
295 if (&codeLabels_.at(i)->address().space() ==
296 &address.space() &&
297 codeLabels_.at(i)->address().location() ==
298 address.location()) {
299
300 found++;
301 if (found == index) {
302 return *codeLabels_.at(i);
303 }
304 }
305 }
306
307 throw KeyNotFound(__FILE__, __LINE__);
308
309 } else {
310 throw OutOfRange(__FILE__, __LINE__);
311 }
312}
313
314/**
315 * Returns the number of data labels in the given address visible in this
316 * scope.
317 *
318 * @param address The address of the label.
319 * @return The number of data labels in the given address visible in this
320 * scope.
321 */
322int
324 int count = 0;
325 for (unsigned int i = 0; i < dataLabels_.size(); i++) {
326 if (&dataLabels_.at(i)->address().space() == &address.space() &&
327 dataLabels_.at(i)->address().location() == address.location()) {
328 count++;
329 }
330 }
331 return count;
332}
333
334/**
335 * Returns a data label visible in this scope in the given address and index.
336 *
337 * @param address The address of the data label.
338 * @param index The index of the label if there area many labels at this
339 * address.
340 * @return A data label visible in this scope in the given address and index.
341 */
342const DataLabel&
343Scope::dataLabel(Address address, int index) const {
344 if (index < dataLabelCount(address)) {
345
346 int found = -1;
347 for (unsigned int i = 0; i < dataLabels_.size(); i++) {
348
349 if (&dataLabels_.at(i)->address().space() ==
350 &address.space() &&
351 dataLabels_.at(i)->address().location() ==
352 address.location()) {
353
354 found++;
355 if (found == index) {
356 return *dataLabels_.at(i);
357 }
358 }
359 }
360
361 throw KeyNotFound(__FILE__, __LINE__);
362
363 } else {
364 throw OutOfRange(__FILE__, __LINE__);
365 }
366}
367
368/**
369 * Adds a code label to this scope.
370 *
371 * @param codeLabel The code label to be added.
372 * @exception KeyAlreadyExists of a code label of the same name already
373 * exists.
374 */
375void
378 throw KeyAlreadyExists(
379 __FILE__, __LINE__, "Scope::addCodeLabel()",
380 "A code label already exists by this name.");
381
382 } else {
383 codeLabels_.push_back(codeLabel);
384
385 // add label to the global bookkeeping
386 Scope* scope = NULL;
387
388 if (!isGlobal()) {
389 scope = &parent();
390 while (!scope->isGlobal()) {
391 try {
392 scope = &scope->parent();
393 } catch (WrongSubclass const&) {
394 assert(false);
395 } catch (IllegalRegistration const&) {
396 assert(false);
397 }
398 }
399 } else {
400 scope = this;
401 }
402
403 scope->addGlobalCodeLabel(*codeLabel, *this);
404 }
405}
406
407/**
408 * Adds a data label to this scope.
409 *
410 * @param dataLabel The data label to be added.
411 * @exception KeyAlreadyExists of a data label of the same name already
412 * exists.
413 */
414void
417 throw KeyAlreadyExists(
418 __FILE__, __LINE__, "Scope::addDataLabel()",
419 "A data label already exists by this name.");
420 } else {
421 dataLabels_.push_back(dataLabel);
422
423 // add label to the global bookkeeping
424 Scope* scope = NULL;
425
426 if (!isGlobal()) {
427 scope = &parent();
428 while (!scope->isGlobal()) {
429 try {
430 scope = &scope->parent();
431 } catch (WrongSubclass const&) {
432 assert(false);
433 } catch (IllegalRegistration const&) {
434 assert(false);
435 }
436 }
437 } else {
438 scope = this;
439 }
440
441 scope->addGlobalDataLabel(*dataLabel, *this);
442 }
443}
444
445/**
446 * Removes all code labels attached to the given instruction address.
447 *
448 * @param address The instruction address.
449 */
450void
452
453 for (CodeLabelList::iterator i = codeLabels_.begin();
454 i != codeLabels_.end(); ) {
455 CodeLabelList::iterator next = i;
456 next++;
457 if ((*i)->address().location() == address) {
458 delete (*i);
459 codeLabels_.erase(i);
460 }
461 i = next;
462 }
463}
464
465}
#define assert(condition)
UInt32 InstructionAddress
Definition BaseType.hh:175
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
const TTAMachine::AddressSpace & space() const
InstructionAddress location() const
std::string name() const
Definition Label.cc:74
ScopeList children_
Child scopes.
Definition Scope.hh:85
int codeLabelCount(Address address) const
Definition Scope.cc:269
virtual void addGlobalDataLabel(const DataLabel &dataLabel, const Scope &owner)=0
Adds a data label and its owner to the global label bookkeeping.
virtual bool isProcedure() const
Definition Scope.cc:92
int dataLabelCount(Address address) const
Definition Scope.cc:323
bool containsDataLabel(const std::string &name) const
Definition Scope.cc:215
virtual bool isUnit() const
Definition Scope.cc:82
void setParent(Scope &scope)
Definition Scope.cc:152
Scope & parent() const
Definition Scope.cc:132
virtual void removeCodeLabels(InstructionAddress address)
Definition Scope.cc:451
int childCount() const
Definition Scope.cc:171
virtual void addDataLabel(const DataLabel *dataLabel)
Definition Scope.cc:415
Scope * parent_
The smallest outer scope that contains this scope.
Definition Scope.hh:125
bool containsCodeLabel(const std::string &name) const
Definition Scope.cc:199
DataLabelList dataLabels_
Data labels contained by this scope.
Definition Scope.hh:93
const CodeLabel & codeLabel(const std::string &name) const
Definition Scope.cc:233
CodeLabelList codeLabels_
Code labels contained by this scope.
Definition Scope.hh:95
const DataLabel & dataLabel(const std::string &name) const
Definition Scope.cc:251
virtual void addGlobalCodeLabel(const CodeLabel &codeLabel, const Scope &owner)=0
Adds a code label and its owner to the global label bookkeeping.
virtual bool isGlobal() const
Definition Scope.cc:72
void addChild(const Scope &scope)
Definition Scope.cc:114
virtual ~Scope()
Definition Scope.cc:54
virtual bool isLocal() const
Definition Scope.cc:102
const Scope & child(int index) const
Definition Scope.cc:184
virtual void addCodeLabel(const CodeLabel *codeLabel)
Definition Scope.cc:376