2011-04-14 03:30:00 +02:00
|
|
|
/*
|
2014-06-30 05:38:23 +02:00
|
|
|
* Copyright (c) 2011-2014 Stephen Williams (steve@icarus.com)
|
2013-06-08 00:47:14 +02:00
|
|
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
2011-04-14 03:30:00 +02:00
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-08-29 03:41:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2011-04-14 03:30:00 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include "scope.h"
|
2013-05-19 02:36:29 +02:00
|
|
|
# include "package.h"
|
2014-09-29 11:31:18 +02:00
|
|
|
# include "subprogram.h"
|
2015-01-26 11:14:31 +01:00
|
|
|
# include "entity.h"
|
2015-06-10 18:41:51 +02:00
|
|
|
# include "std_funcs.h"
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
# include <algorithm>
|
2011-04-18 02:19:09 +02:00
|
|
|
# include <iostream>
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
# include <iterator>
|
2013-05-19 02:36:29 +02:00
|
|
|
# include <cassert>
|
2011-04-14 03:30:00 +02:00
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
2012-03-18 20:49:19 +01:00
|
|
|
/*
|
|
|
|
|
* If the merge_flag is passed in, then the new scope is a merge of
|
|
|
|
|
* the parent scopes. This brings in all of the parent scopes into the
|
|
|
|
|
* "old_*_" variables. This clears up the "new_*_" variables to
|
|
|
|
|
* accumulate new scope values.
|
|
|
|
|
*/
|
2013-05-13 04:17:12 +02:00
|
|
|
ScopeBase::ScopeBase(const ActiveScope&ref)
|
2014-06-30 05:38:23 +02:00
|
|
|
: use_constants_(ref.use_constants_), cur_constants_(ref.cur_constants_)
|
2011-04-14 03:30:00 +02:00
|
|
|
{
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
merge(ref.old_signals_.begin(), ref.old_signals_.end(),
|
|
|
|
|
ref.new_signals_.begin(), ref.new_signals_.end(),
|
|
|
|
|
insert_iterator<map<perm_string, Signal*> >(
|
|
|
|
|
old_signals_, old_signals_.end())
|
|
|
|
|
);
|
2011-08-18 05:19:15 +02:00
|
|
|
merge(ref.old_variables_.begin(), ref.old_variables_.end(),
|
|
|
|
|
ref.new_variables_.begin(), ref.new_variables_.end(),
|
|
|
|
|
insert_iterator<map<perm_string, Variable*> >(
|
|
|
|
|
old_variables_, old_variables_.end())
|
|
|
|
|
);
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
merge(ref.old_components_.begin(), ref.old_components_.end(),
|
|
|
|
|
ref.new_components_.begin(), ref.new_components_.end(),
|
|
|
|
|
insert_iterator<map<perm_string, ComponentBase*> >(
|
|
|
|
|
old_components_, old_components_.end())
|
|
|
|
|
);
|
2013-05-13 04:17:12 +02:00
|
|
|
use_types_ = ref.use_types_;
|
|
|
|
|
cur_types_ = ref.cur_types_;
|
2013-05-19 02:36:29 +02:00
|
|
|
|
|
|
|
|
use_subprograms_ = ref.use_subprograms_;
|
|
|
|
|
cur_subprograms_ = ref.cur_subprograms_;
|
2013-06-08 00:47:14 +02:00
|
|
|
|
2015-02-06 10:44:22 +01:00
|
|
|
use_enums_ = ref.use_enums_;
|
|
|
|
|
|
2013-06-08 00:47:14 +02:00
|
|
|
// This constructor is invoked when the parser is finished with
|
|
|
|
|
// an active scope and is making the actual scope. At this point
|
|
|
|
|
// we know that "this" is the parent scope for the subprograms,
|
|
|
|
|
// so set it now.
|
2015-06-10 11:29:37 +02:00
|
|
|
for (map<perm_string,SubprogramHeader*>::iterator cur = cur_subprograms_.begin()
|
|
|
|
|
; cur != cur_subprograms_.end(); ++cur) {
|
|
|
|
|
cur->second->set_parent(this);
|
2013-06-08 00:47:14 +02:00
|
|
|
}
|
2011-04-14 03:30:00 +02:00
|
|
|
}
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
ScopeBase::~ScopeBase()
|
2011-04-14 03:30:00 +02:00
|
|
|
{
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
//freeing of member objects is performed by child classes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScopeBase::cleanup()
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* A parent scope is destroyed only if all child scopes
|
|
|
|
|
* were previously destroyed. There for we can delete all
|
|
|
|
|
* objects that were defined in this scope, leaving
|
|
|
|
|
* objects from the other scopes untouched.
|
|
|
|
|
*/
|
2011-07-21 11:04:48 +02:00
|
|
|
delete_all(new_signals_);
|
|
|
|
|
delete_all(new_components_);
|
2013-05-13 04:17:12 +02:00
|
|
|
delete_all(cur_types_);
|
|
|
|
|
delete_all(cur_constants_);
|
2013-05-19 02:36:29 +02:00
|
|
|
delete_all(cur_subprograms_);
|
2011-04-14 03:30:00 +02:00
|
|
|
}
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
const VType*ScopeBase::find_type(perm_string by_name)
|
2011-04-14 03:30:00 +02:00
|
|
|
{
|
2013-05-13 04:17:12 +02:00
|
|
|
map<perm_string,const VType*>::const_iterator cur = cur_types_.find(by_name);
|
|
|
|
|
if (cur == cur_types_.end()) {
|
|
|
|
|
cur = use_types_.find(by_name);
|
|
|
|
|
if (cur == use_types_.end())
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return cur->second;
|
|
|
|
|
} else
|
2011-04-14 03:30:00 +02:00
|
|
|
return cur->second;
|
|
|
|
|
}
|
2011-04-14 04:55:18 +02:00
|
|
|
|
2015-02-16 12:06:33 +01:00
|
|
|
bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const
|
2011-04-18 02:19:09 +02:00
|
|
|
{
|
2015-02-19 17:01:14 +01:00
|
|
|
typ = NULL;
|
|
|
|
|
exp = NULL;
|
|
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.find(by_name);
|
|
|
|
|
if (cur == cur_constants_.end()) {
|
|
|
|
|
cur = use_constants_.find(by_name);
|
|
|
|
|
if (cur == use_constants_.end())
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
return false;
|
|
|
|
|
else {
|
|
|
|
|
typ = cur->second->typ;
|
|
|
|
|
exp = cur->second->val;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
typ = cur->second->typ;
|
|
|
|
|
exp = cur->second->val;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2015-02-19 17:01:14 +01:00
|
|
|
|
|
|
|
|
return false;
|
2011-04-18 02:19:09 +02:00
|
|
|
}
|
|
|
|
|
|
2011-08-29 00:30:45 +02:00
|
|
|
Signal* ScopeBase::find_signal(perm_string by_name) const
|
|
|
|
|
{
|
|
|
|
|
map<perm_string,Signal*>::const_iterator cur = new_signals_.find(by_name);
|
|
|
|
|
if (cur == new_signals_.end()) {
|
|
|
|
|
cur = old_signals_.find(by_name);
|
|
|
|
|
if (cur == old_signals_.end())
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return cur->second;
|
|
|
|
|
} else {
|
|
|
|
|
return cur->second;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Variable* ScopeBase::find_variable(perm_string by_name) const
|
|
|
|
|
{
|
|
|
|
|
map<perm_string,Variable*>::const_iterator cur = new_variables_.find(by_name);
|
|
|
|
|
if (cur == new_variables_.end()) {
|
|
|
|
|
cur = old_variables_.find(by_name);
|
|
|
|
|
if (cur == old_variables_.end())
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return cur->second;
|
|
|
|
|
} else {
|
|
|
|
|
return cur->second;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-26 11:14:31 +01:00
|
|
|
const InterfacePort* ScopeBase::find_param(perm_string by_name) const
|
|
|
|
|
{
|
2015-06-10 11:29:37 +02:00
|
|
|
for(map<perm_string,SubprogramHeader*>::const_iterator it = use_subprograms_.begin();
|
2015-01-26 11:14:31 +01:00
|
|
|
it != use_subprograms_.end(); ++it) {
|
|
|
|
|
if(const InterfacePort*port = it->second->find_param(by_name))
|
|
|
|
|
return port;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
for(map<perm_string,SubprogramHeader*>::const_iterator it = cur_subprograms_.begin();
|
2015-01-26 11:14:31 +01:00
|
|
|
it != cur_subprograms_.end(); ++it) {
|
|
|
|
|
if(const InterfacePort*port = it->second->find_param(by_name))
|
|
|
|
|
return port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
SubprogramHeader* ScopeBase::find_subprogram(perm_string name) const
|
2013-05-19 02:36:29 +02:00
|
|
|
{
|
2015-06-10 11:29:37 +02:00
|
|
|
map<perm_string,SubprogramHeader*>::const_iterator cur;
|
2013-05-19 02:36:29 +02:00
|
|
|
|
|
|
|
|
cur = cur_subprograms_.find(name);
|
|
|
|
|
if (cur != cur_subprograms_.end())
|
|
|
|
|
return cur->second;
|
|
|
|
|
|
|
|
|
|
cur = use_subprograms_.find(name);
|
2013-06-08 00:47:14 +02:00
|
|
|
if (cur != use_subprograms_.end())
|
2013-05-19 02:36:29 +02:00
|
|
|
return cur->second;
|
|
|
|
|
|
2015-06-10 18:41:51 +02:00
|
|
|
return find_std_subprogram(name);
|
2013-05-19 02:36:29 +02:00
|
|
|
}
|
|
|
|
|
|
2015-05-07 14:42:31 +02:00
|
|
|
const VTypeEnum* ScopeBase::is_enum_name(perm_string name) const
|
2015-02-06 10:44:22 +01:00
|
|
|
{
|
|
|
|
|
for(list<const VTypeEnum*>::const_iterator it = use_enums_.begin();
|
|
|
|
|
it != use_enums_.end(); ++it) {
|
|
|
|
|
if((*it)->has_name(name))
|
2015-05-07 14:42:31 +02:00
|
|
|
return *it;
|
2015-02-06 10:44:22 +01:00
|
|
|
}
|
|
|
|
|
|
2015-05-07 14:42:31 +02:00
|
|
|
return NULL;
|
2015-02-06 10:44:22 +01:00
|
|
|
}
|
|
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
/*
|
|
|
|
|
* This method is only used by the ActiveScope derived class to import
|
|
|
|
|
* definition from another scope.
|
|
|
|
|
*/
|
2011-04-18 02:19:09 +02:00
|
|
|
void ScopeBase::do_use_from(const ScopeBase*that)
|
2011-04-14 04:55:18 +02:00
|
|
|
{
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
for (map<perm_string,ComponentBase*>::const_iterator cur = that->old_components_.begin()
|
|
|
|
|
; cur != that->old_components_.end() ; ++ cur) {
|
2011-04-14 04:55:18 +02:00
|
|
|
if (cur->second == 0)
|
|
|
|
|
continue;
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
old_components_[cur->first] = cur->second;
|
|
|
|
|
}
|
2013-05-06 04:05:46 +02:00
|
|
|
for (map<perm_string,ComponentBase*>::const_iterator cur = that->new_components_.begin()
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
; cur != that->new_components_.end() ; ++ cur) {
|
|
|
|
|
if (cur->second == 0)
|
|
|
|
|
continue;
|
|
|
|
|
old_components_[cur->first] = cur->second;
|
2011-04-14 04:55:18 +02:00
|
|
|
}
|
2011-04-18 02:19:09 +02:00
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
for (map<perm_string,SubprogramHeader*>::const_iterator cur = that->cur_subprograms_.begin()
|
2013-05-19 02:36:29 +02:00
|
|
|
; cur != that->cur_subprograms_.end() ; ++ cur) {
|
2013-05-06 04:05:46 +02:00
|
|
|
if (cur->second == 0)
|
|
|
|
|
continue;
|
2013-05-19 02:36:29 +02:00
|
|
|
use_subprograms_[cur->first] = cur->second;
|
2013-05-06 04:05:46 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-19 02:36:29 +02:00
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
for (map<perm_string,const VType*>::const_iterator cur = that->cur_types_.begin()
|
|
|
|
|
; cur != that->cur_types_.end() ; ++ cur) {
|
2011-04-18 02:19:09 +02:00
|
|
|
if (cur->second == 0)
|
|
|
|
|
continue;
|
2013-05-13 04:17:12 +02:00
|
|
|
use_types_[cur->first] = cur->second;
|
2011-04-18 02:19:09 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
for (map<perm_string,const_t*>::const_iterator cur = that->cur_constants_.begin()
|
|
|
|
|
; cur != that->cur_constants_.end() ; ++ cur) {
|
|
|
|
|
use_constants_[cur->first] = cur->second;
|
2011-04-18 02:19:09 +02:00
|
|
|
}
|
2015-02-06 10:44:22 +01:00
|
|
|
|
|
|
|
|
use_enums_ = that->use_enums_;
|
2011-04-18 02:19:09 +02:00
|
|
|
}
|
|
|
|
|
|
2015-03-31 10:46:24 +02:00
|
|
|
void ScopeBase::transfer_from(ScopeBase&ref, transfer_type_t what)
|
2014-09-29 11:38:54 +02:00
|
|
|
{
|
2015-03-31 10:46:24 +02:00
|
|
|
if(what & SIGNALS) {
|
|
|
|
|
std::copy(ref.new_signals_.begin(), ref.new_signals_.end(),
|
|
|
|
|
insert_iterator<map<perm_string, Signal*> >(
|
|
|
|
|
new_signals_, new_signals_.end())
|
|
|
|
|
);
|
|
|
|
|
ref.new_signals_.clear();
|
|
|
|
|
}
|
2014-09-29 11:38:54 +02:00
|
|
|
|
2015-03-31 10:46:24 +02:00
|
|
|
if(what & VARIABLES) {
|
|
|
|
|
std::copy(ref.new_variables_.begin(), ref.new_variables_.end(),
|
|
|
|
|
insert_iterator<map<perm_string, Variable*> >(
|
|
|
|
|
new_variables_, new_variables_.end())
|
|
|
|
|
);
|
|
|
|
|
ref.new_variables_.clear();
|
|
|
|
|
}
|
2014-09-29 11:38:54 +02:00
|
|
|
|
2015-03-31 10:46:24 +02:00
|
|
|
if(what & COMPONENTS) {
|
|
|
|
|
std::copy(ref.new_components_.begin(), ref.new_components_.end(),
|
|
|
|
|
insert_iterator<map<perm_string, ComponentBase*> >(
|
|
|
|
|
new_components_, new_components_.end())
|
|
|
|
|
);
|
|
|
|
|
ref.new_components_.clear();
|
|
|
|
|
}
|
2014-09-29 11:38:54 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-19 02:36:29 +02:00
|
|
|
void ActiveScope::set_package_header(Package*pkg)
|
|
|
|
|
{
|
|
|
|
|
assert(package_header_ == 0);
|
|
|
|
|
package_header_ = pkg;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
SubprogramHeader* ActiveScope::recall_subprogram(perm_string name) const
|
2013-05-19 02:36:29 +02:00
|
|
|
{
|
2015-06-10 11:29:37 +02:00
|
|
|
if (SubprogramHeader*tmp = find_subprogram(name))
|
2013-05-19 02:36:29 +02:00
|
|
|
return tmp;
|
|
|
|
|
|
|
|
|
|
if (package_header_)
|
|
|
|
|
return package_header_->find_subprogram(name);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-29 00:30:45 +02:00
|
|
|
bool ActiveScope::is_vector_name(perm_string name) const
|
|
|
|
|
{
|
|
|
|
|
if (find_signal(name))
|
|
|
|
|
return true;
|
|
|
|
|
if (find_variable(name))
|
|
|
|
|
return true;
|
|
|
|
|
|
2015-02-16 12:06:33 +01:00
|
|
|
const VType*dummy_type;
|
|
|
|
|
Expression*dummy_exp;
|
|
|
|
|
if (find_constant(name, dummy_type, dummy_exp))
|
|
|
|
|
return true;
|
|
|
|
|
|
2011-09-12 00:28:58 +02:00
|
|
|
if (context_entity_ && context_entity_->find_port(name))
|
|
|
|
|
return true;
|
|
|
|
|
|
2011-08-29 00:30:45 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
Scope::Scope(const ActiveScope&ref)
|
2011-04-18 02:19:09 +02:00
|
|
|
: ScopeBase(ref)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Scope::~Scope()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ComponentBase* Scope::find_component(perm_string by_name)
|
|
|
|
|
{
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
map<perm_string,ComponentBase*>::const_iterator cur = new_components_.find(by_name);
|
|
|
|
|
if (cur == new_components_.end()) {
|
|
|
|
|
cur = old_components_.find(by_name);
|
|
|
|
|
if (cur == old_components_.end())
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return cur->second;
|
|
|
|
|
} else
|
2011-04-18 02:19:09 +02:00
|
|
|
return cur->second;
|
2011-04-14 04:55:18 +02:00
|
|
|
}
|