2014-07-23 22:39:29 +02:00
|
|
|
#ifndef IVL_scope_H
|
|
|
|
|
#define IVL_scope_H
|
2011-04-14 03:30:00 +02:00
|
|
|
/*
|
2014-07-23 22:39:29 +02:00
|
|
|
* Copyright (c) 2011-2014 Stephen Williams (steve@icarus.com)
|
2013-05-13 04:17:12 +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
|
|
|
*/
|
|
|
|
|
|
2011-07-21 11:04:48 +02:00
|
|
|
# include <algorithm>
|
2011-04-14 04:55:18 +02:00
|
|
|
# include <list>
|
2011-04-14 03:30:00 +02:00
|
|
|
# include <map>
|
|
|
|
|
# include "StringHeap.h"
|
2013-05-06 04:05:46 +02:00
|
|
|
# include "entity.h"
|
|
|
|
|
# include "expression.h"
|
|
|
|
|
# include "vsignal.h"
|
2011-04-14 03:30:00 +02:00
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
class ActiveScope;
|
2011-04-18 02:19:09 +02:00
|
|
|
class Architecture;
|
2011-04-14 03:30:00 +02:00
|
|
|
class ComponentBase;
|
2013-05-13 04:17:12 +02:00
|
|
|
class Package;
|
2015-06-10 11:29:37 +02:00
|
|
|
class SubprogramHeader;
|
2011-04-14 03:30:00 +02:00
|
|
|
class VType;
|
|
|
|
|
|
2011-07-21 11:04:48 +02:00
|
|
|
template<typename T>
|
|
|
|
|
struct delete_object{
|
|
|
|
|
void operator()(T* item) { delete item; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
struct delete_pair_second{
|
|
|
|
|
void operator()(pair<perm_string, T*> item){ delete item.second; }
|
|
|
|
|
};
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
class ScopeBase {
|
2011-04-14 03:30:00 +02:00
|
|
|
|
|
|
|
|
public:
|
2011-04-18 02:19:09 +02:00
|
|
|
ScopeBase() { }
|
2013-05-13 04:17:12 +02:00
|
|
|
explicit ScopeBase(const ActiveScope&ref);
|
2011-04-18 02:19:09 +02:00
|
|
|
virtual ~ScopeBase() =0;
|
|
|
|
|
|
|
|
|
|
const VType* find_type(perm_string by_name);
|
2015-03-06 16:59:30 +01:00
|
|
|
virtual bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
|
2011-08-29 00:30:45 +02:00
|
|
|
Signal* find_signal(perm_string by_name) const;
|
|
|
|
|
Variable* find_variable(perm_string by_name) const;
|
2015-01-26 11:14:31 +01:00
|
|
|
virtual const InterfacePort* find_param(perm_string by_name) const;
|
2015-06-22 14:03:59 +02:00
|
|
|
const InterfacePort* find_param_all(perm_string by_name) const;
|
2015-06-10 11:29:37 +02:00
|
|
|
SubprogramHeader* find_subprogram(perm_string by_name) const;
|
2015-05-07 14:42:31 +02:00
|
|
|
// Checks if a string is one of possible enum values. If so, the enum
|
|
|
|
|
// type is returned, otherwise NULL.
|
|
|
|
|
const VTypeEnum* is_enum_name(perm_string name) const;
|
2015-03-31 10:46:24 +02:00
|
|
|
|
|
|
|
|
// Moves signals, variables and components from another scope to
|
|
|
|
|
// this one. After the transfer new_* maps are cleared in the source scope.
|
|
|
|
|
enum transfer_type_t { SIGNALS = 1, VARIABLES = 2, COMPONENTS = 4, ALL = 0xffff };
|
|
|
|
|
void transfer_from(ScopeBase&ref, transfer_type_t what = ALL);
|
2011-08-29 00:30:45 +02:00
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
inline void bind_subprogram(perm_string name, SubprogramHeader*obj)
|
|
|
|
|
{ map<perm_string, SubprogramHeader*>::iterator it;
|
2015-02-02 11:50:50 +01:00
|
|
|
if((it = use_subprograms_.find(name)) != use_subprograms_.end() )
|
|
|
|
|
use_subprograms_.erase(it);
|
|
|
|
|
cur_subprograms_[name] = obj;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
protected:
|
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
|
|
|
void cleanup();
|
|
|
|
|
|
2011-07-21 11:04:48 +02:00
|
|
|
//containers' cleaning helper functions
|
|
|
|
|
template<typename T> void delete_all(list<T*>& c)
|
|
|
|
|
{
|
|
|
|
|
for_each(c.begin(), c.end(), ::delete_object<T>());
|
|
|
|
|
}
|
|
|
|
|
template<typename T> void delete_all(map<perm_string, T*>& c)
|
|
|
|
|
{
|
|
|
|
|
for_each(c.begin(), c.end(), ::delete_pair_second<T>());
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
// The new_*_ maps below are managed only by the ActiveScope
|
|
|
|
|
// derived class. When any scope is constructed from the
|
|
|
|
|
// ActiveScope, the new_*_ and old_*_ maps are merged and
|
|
|
|
|
// installed into the old_*_ maps. Thus, all other derived
|
|
|
|
|
// classes should only use the old_*_ maps.
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
// Signal declarations...
|
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
|
|
|
std::map<perm_string,Signal*> old_signals_; //previous scopes
|
|
|
|
|
std::map<perm_string,Signal*> new_signals_; //current scope
|
2011-08-18 05:19:15 +02:00
|
|
|
// Variable declarations...
|
|
|
|
|
std::map<perm_string,Variable*> old_variables_; //previous scopes
|
|
|
|
|
std::map<perm_string,Variable*> new_variables_; //current scope
|
2011-04-26 23:18:30 +02:00
|
|
|
// Component declarations...
|
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
|
|
|
std::map<perm_string,ComponentBase*> old_components_; //previous scopes
|
|
|
|
|
std::map<perm_string,ComponentBase*> new_components_; //current scope
|
2011-04-18 02:19:09 +02:00
|
|
|
// Type declarations...
|
2013-05-13 04:17:12 +02:00
|
|
|
std::map<perm_string,const VType*> use_types_; //imported types
|
|
|
|
|
std::map<perm_string,const VType*> cur_types_; //current types
|
2011-04-18 02:19:09 +02:00
|
|
|
// Constant declarations...
|
|
|
|
|
struct const_t {
|
2014-08-06 15:01:59 +02:00
|
|
|
~const_t() {delete val;}
|
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
|
|
|
const_t(const VType*t, Expression* v) : typ(t), val(v) {};
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
const VType*typ;
|
|
|
|
|
Expression*val;
|
|
|
|
|
};
|
2013-05-13 04:17:12 +02:00
|
|
|
std::map<perm_string, struct const_t*> use_constants_; //imported constants
|
|
|
|
|
std::map<perm_string, struct const_t*> cur_constants_; //current constants
|
2011-04-18 02:19:09 +02:00
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
std::map<perm_string, SubprogramHeader*> use_subprograms_; //imported
|
|
|
|
|
std::map<perm_string, SubprogramHeader*> cur_subprograms_; //current
|
2013-05-06 04:05:46 +02:00
|
|
|
|
2015-02-06 10:44:22 +01:00
|
|
|
std::list<const VTypeEnum*> use_enums_;
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
void do_use_from(const ScopeBase*that);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Scope : public ScopeBase {
|
|
|
|
|
|
|
|
|
|
public:
|
2013-05-13 04:17:12 +02:00
|
|
|
explicit Scope(const ActiveScope&ref);
|
2011-04-14 03:30:00 +02:00
|
|
|
~Scope();
|
|
|
|
|
|
|
|
|
|
ComponentBase* find_component(perm_string by_name);
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
public:
|
2011-04-14 03:30:00 +02:00
|
|
|
void dump_scope(ostream&out) const;
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
protected:
|
|
|
|
|
// Helper method for emitting signals in the scope.
|
|
|
|
|
int emit_signals(ostream&out, Entity*ent, Architecture*arc);
|
2011-08-18 05:19:15 +02:00
|
|
|
int emit_variables(ostream&out, Entity*ent, Architecture*arc);
|
2011-04-18 02:19:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The active_scope object accumulates declarations for the scope that
|
|
|
|
|
* is in the process of being parsed. When the declarations are over,
|
|
|
|
|
* they are transferred over to the specific scope. The ActiveScope is
|
|
|
|
|
* used by the parser to build up scopes.
|
|
|
|
|
*/
|
|
|
|
|
class ActiveScope : public ScopeBase {
|
|
|
|
|
|
|
|
|
|
public:
|
2013-05-19 02:36:29 +02:00
|
|
|
ActiveScope() : package_header_(0), context_entity_(0) { }
|
|
|
|
|
ActiveScope(ActiveScope*par) : ScopeBase(*par), package_header_(0), context_entity_(0) { }
|
2011-04-26 23:18:30 +02:00
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
~ActiveScope() { }
|
|
|
|
|
|
2013-05-19 02:36:29 +02:00
|
|
|
void set_package_header(Package*);
|
|
|
|
|
|
|
|
|
|
// Pull items from "that" scope into "this" scope as is
|
|
|
|
|
// defined by a "use" directive. The parser uses this method
|
|
|
|
|
// to implement the "use <pkg>::*" directive.
|
2013-05-13 04:17:12 +02:00
|
|
|
void use_from(const Scope*that) { do_use_from(that); }
|
2011-04-18 02:19:09 +02:00
|
|
|
|
2011-08-29 00:30:45 +02:00
|
|
|
// This function returns true if the name is a vectorable
|
|
|
|
|
// name. The parser uses this to distinguish between function
|
|
|
|
|
// calls and array index operations.
|
|
|
|
|
bool is_vector_name(perm_string name) const;
|
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
|
|
|
|
2013-05-19 02:36:29 +02:00
|
|
|
// Locate the subprogram by name. The subprogram body uses
|
|
|
|
|
// this to locate the sobprogram declaration. Note that the
|
|
|
|
|
// subprogram may be in a package header.
|
2015-06-10 11:29:37 +02:00
|
|
|
SubprogramHeader* recall_subprogram(perm_string name) const;
|
2013-05-19 02:36:29 +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
|
|
|
/* All bind_name function check if the given name was present
|
|
|
|
|
* in previous scopes. If it is found, it is erased (but the pointer
|
|
|
|
|
* is not freed), in order to implement name shadowing. The pointer
|
|
|
|
|
* be freed only in the scope where the object was defined. This is
|
|
|
|
|
* done in ScopeBase::cleanup() function .*/
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
void bind_name(perm_string name, Signal*obj)
|
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, Signal*>::iterator it;
|
|
|
|
|
if((it = old_signals_.find(name)) != old_signals_.end() )
|
|
|
|
|
old_signals_.erase(it);
|
|
|
|
|
new_signals_[name] = obj;
|
|
|
|
|
}
|
2011-04-18 02:19:09 +02:00
|
|
|
|
2011-08-18 05:19:15 +02:00
|
|
|
void bind_name(perm_string name, Variable*obj)
|
|
|
|
|
{ map<perm_string, Variable*>::iterator it;
|
|
|
|
|
if((it = old_variables_.find(name)) != old_variables_.end() )
|
|
|
|
|
old_variables_.erase(it);
|
|
|
|
|
new_variables_[name] = obj;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
void bind_name(perm_string name, ComponentBase*obj)
|
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*>::iterator it;
|
|
|
|
|
if((it = old_components_.find(name)) != old_components_.end() )
|
|
|
|
|
old_components_.erase(it);
|
|
|
|
|
new_components_[name] = obj;
|
|
|
|
|
}
|
2011-04-18 02:19:09 +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
|
|
|
void bind_name(perm_string name, const VType* t)
|
|
|
|
|
{ map<perm_string, const VType*>::iterator it;
|
2013-05-13 04:17:12 +02:00
|
|
|
if((it = use_types_.find(name)) != use_types_.end() )
|
|
|
|
|
use_types_.erase(it);
|
|
|
|
|
cur_types_[name] = t;
|
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
|
|
|
}
|
2011-04-18 02:19:09 +02:00
|
|
|
|
2015-02-06 10:44:22 +01:00
|
|
|
inline void use_enum(const VTypeEnum* t)
|
|
|
|
|
{ use_enums_.push_back(t); }
|
|
|
|
|
|
2013-05-13 04:17:12 +02:00
|
|
|
inline void use_name(perm_string name, const VType* t)
|
|
|
|
|
{ use_types_[name] = t; }
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
void bind_name(perm_string name, const VType*obj, Expression*val)
|
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, const_t*>::iterator it;
|
2013-05-13 04:17:12 +02:00
|
|
|
if((it = use_constants_.find(name)) != use_constants_.end() )
|
|
|
|
|
use_constants_.erase(it);
|
|
|
|
|
cur_constants_[name] = new const_t(obj, val);
|
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
|
|
|
}
|
2011-07-29 01:40:15 +02:00
|
|
|
|
2015-06-10 11:29:37 +02:00
|
|
|
inline void bind_name(perm_string name, SubprogramHeader*obj)
|
|
|
|
|
{ map<perm_string, SubprogramHeader*>::iterator it;
|
2013-05-19 02:36:29 +02:00
|
|
|
if((it = use_subprograms_.find(name)) != use_subprograms_.end() )
|
|
|
|
|
use_subprograms_.erase(it);
|
2014-09-29 11:38:54 +02:00
|
|
|
cur_subprograms_[name] = obj;
|
2013-05-06 04:05:46 +02:00
|
|
|
}
|
|
|
|
|
|
2011-09-12 00:28:58 +02:00
|
|
|
void bind(Entity*ent)
|
|
|
|
|
{ context_entity_ = ent; }
|
|
|
|
|
|
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
|
|
|
void destroy_global_scope()
|
2011-04-18 02:19:09 +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
|
|
|
cleanup();
|
2011-04-18 02:19:09 +02:00
|
|
|
}
|
2011-09-12 00:28:58 +02:00
|
|
|
|
2012-05-06 00:15:45 +02:00
|
|
|
// Keep track of incomplete types until their proper
|
|
|
|
|
// definition shows up.
|
|
|
|
|
std::map<perm_string,VTypeDef*> incomplete_types;
|
|
|
|
|
|
2011-09-12 00:28:58 +02:00
|
|
|
private:
|
2013-05-19 02:36:29 +02:00
|
|
|
// If this is a package body, then there is a Package header
|
|
|
|
|
// already declared.
|
|
|
|
|
Package*package_header_;
|
|
|
|
|
|
2011-09-12 00:28:58 +02:00
|
|
|
Entity*context_entity_;
|
2011-04-14 03:30:00 +02:00
|
|
|
};
|
|
|
|
|
|
2014-07-23 22:39:29 +02:00
|
|
|
#endif /* IVL_scope_H */
|