vhdlpp: Support for subprogram overloading.
This commit is contained in:
parent
cfa038e75c
commit
2c4deee0c3
|
|
@ -61,9 +61,14 @@ int Architecture::elaborate(Entity*entity)
|
|||
}
|
||||
|
||||
// Elaborate subprograms
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
errors += cur->second->elaborate();
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
errors += (*it)->elaborate();
|
||||
}
|
||||
}
|
||||
// Create 'initial' and 'final' blocks for implicit
|
||||
// initalization and clean-up actions
|
||||
|
|
|
|||
|
|
@ -103,11 +103,18 @@ int Architecture::emit(ostream&out, Entity*entity)
|
|||
errors += emit_signals(out, entity, this);
|
||||
errors += emit_variables(out, entity, this);
|
||||
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++ cur) {
|
||||
// Do not emit unbounded functions, we will just need fixed instances later
|
||||
if(!cur->second->unbounded())
|
||||
errors += cur->second->emit_package(out);
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
SubprogramHeader*subp = *it;
|
||||
|
||||
// Do not emit unbounded functions, we will just need fixed instances later
|
||||
if(!subp->unbounded())
|
||||
errors += subp->emit_package(out);
|
||||
}
|
||||
}
|
||||
|
||||
for (list<Architecture::Statement*>::iterator cur = statements_.begin()
|
||||
|
|
|
|||
|
|
@ -150,22 +150,35 @@ void ScopeBase::dump_scope(ostream&out) const
|
|||
}
|
||||
// Dump subprograms
|
||||
out << " -- Imported Subprograms" << endl;
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = use_subprograms_.begin()
|
||||
; cur != use_subprograms_.end() ; ++cur) {
|
||||
out << " subprogram " << cur->first << " is" << endl;
|
||||
cur->second->dump(out);
|
||||
if(cur->second->body())
|
||||
cur->second->body()->dump(out);
|
||||
out << " end subprogram " << cur->first << endl;
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = use_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++ cur) {
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
const SubprogramHeader*subp = *it;
|
||||
out << " subprogram " << cur->first << " is" << endl;
|
||||
subp->dump(out);
|
||||
if(subp->body())
|
||||
subp->body()->dump(out);
|
||||
out << " end subprogram " << cur->first << endl;
|
||||
}
|
||||
}
|
||||
|
||||
out << " -- Subprograms from this scope" << endl;
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
out << " subprogram " << cur->first << " is" << endl;
|
||||
cur->second->dump(out);
|
||||
if(cur->second->body())
|
||||
cur->second->body()->dump(out);
|
||||
out << " end subprogram " << cur->first << endl;
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
const SubprogramHeader*subp = *it;
|
||||
out << " subprogram " << cur->first << " is" << endl;
|
||||
subp->dump(out);
|
||||
if(subp->body())
|
||||
subp->body()->dump(out);
|
||||
out << " end subprogram " << cur->first << endl;
|
||||
}
|
||||
}
|
||||
// Dump component declarations
|
||||
out << " -- Components" << endl;
|
||||
|
|
|
|||
|
|
@ -783,22 +783,29 @@ int ExpConditional::case_t::elaborate_expr(Entity*ent, ScopeBase*scope, const VT
|
|||
return errors;
|
||||
}
|
||||
|
||||
const VType*ExpFunc::probe_type(Entity*, ScopeBase*scope) const
|
||||
const VType*ExpFunc::probe_type(Entity*ent, ScopeBase*scope) const
|
||||
{
|
||||
SubprogramHeader*prog = def_;
|
||||
|
||||
if(!prog) {
|
||||
prog = scope->find_subprogram(name_);
|
||||
}
|
||||
list<const VType*> arg_types;
|
||||
|
||||
if(!prog)
|
||||
prog = library_find_subprogram(name_);
|
||||
for(vector<Expression*>::const_iterator it = argv_.begin();
|
||||
it != argv_.end(); ++it) {
|
||||
arg_types.push_back((*it)->probe_type(ent, scope));
|
||||
}
|
||||
|
||||
if(!prog) {
|
||||
cerr << get_fileline() << ": sorry: could not find function ";
|
||||
emit_subprogram_sig(cerr, name_, arg_types);
|
||||
cerr << endl;
|
||||
ivl_assert(*this, false);
|
||||
prog = scope->match_subprogram(name_, &arg_types);
|
||||
|
||||
if(!prog)
|
||||
prog = library_match_subprogram(name_, &arg_types);
|
||||
|
||||
if(!prog) {
|
||||
cerr << get_fileline() << ": sorry: could not find function ";
|
||||
emit_subprogram_sig(cerr, name_, arg_types);
|
||||
cerr << endl;
|
||||
ivl_assert(*this, false);
|
||||
}
|
||||
}
|
||||
|
||||
return prog->peek_return_type();
|
||||
|
|
@ -808,13 +815,19 @@ int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
ivl_assert(*this, scope);
|
||||
SubprogramHeader*prog = scope->find_subprogram(name_);
|
||||
ivl_assert(*this, def_ == 0); // do not elaborate twice
|
||||
|
||||
if(!prog)
|
||||
prog = library_find_subprogram(name_);
|
||||
// Create a list of argument types to find a matching subprogram
|
||||
list<const VType*> arg_types;
|
||||
for(vector<Expression*>::iterator it = argv_.begin();
|
||||
it != argv_.end(); ++it)
|
||||
arg_types.push_back((*it)->probe_type(ent, scope));
|
||||
|
||||
def_ = scope->match_subprogram(name_, &arg_types);
|
||||
|
||||
if(!def_)
|
||||
def_ = library_match_subprogram(name_, &arg_types);
|
||||
|
||||
def_ = prog;
|
||||
if(!def_) {
|
||||
cerr << get_fileline() << ": error: could not find function ";
|
||||
emit_subprogram_sig(cerr, name_, arg_types);
|
||||
|
|
@ -824,15 +837,15 @@ int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
|
|||
|
||||
// Elaborate arguments
|
||||
for (size_t idx = 0; idx < argv_.size(); ++idx) {
|
||||
errors += prog->elaborate_argument(argv_[idx], idx, ent, scope);
|
||||
errors += def_->elaborate_argument(argv_[idx], idx, ent, scope);
|
||||
}
|
||||
|
||||
// SystemVerilog functions work only with defined size data types, therefore
|
||||
// if header does not specify argument or return type size, create a function
|
||||
// instance that work with this particular size.
|
||||
if(def_ && !def_->is_std() && def_->unbounded()) {
|
||||
def_ = prog->make_instance(argv_, scope);
|
||||
name_ = def_->name();
|
||||
def_ = def_->make_instance(argv_, scope);
|
||||
name_ = def_->name(); // TODO necessary?
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2016
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -73,9 +75,9 @@ void library_add_directory(const char*directory)
|
|||
library_search_path.push_front(directory);
|
||||
}
|
||||
|
||||
SubprogramHeader*library_find_subprogram(perm_string name)
|
||||
SubprogramHeader*library_match_subprogram(perm_string name, const list<const VType*>*params)
|
||||
{
|
||||
SubprogramHeader*subp = NULL;
|
||||
SubprogramHeader*subp;
|
||||
map<perm_string,struct library_contents>::const_iterator lib_it;
|
||||
|
||||
for(lib_it = libraries.begin(); lib_it != libraries.end(); ++lib_it) {
|
||||
|
|
@ -83,7 +85,7 @@ SubprogramHeader*library_find_subprogram(perm_string name)
|
|||
map<perm_string,Package*>::const_iterator pack_it;
|
||||
|
||||
for(pack_it = lib.packages.begin(); pack_it != lib.packages.end(); ++pack_it) {
|
||||
if((subp = pack_it->second->find_subprogram(name)))
|
||||
if((subp = pack_it->second->match_subprogram(name, params)))
|
||||
return subp;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,15 +19,18 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
class SubprogramHeader;
|
||||
#include <list>
|
||||
|
||||
extern void library_set_work_path(const char*work_path);
|
||||
extern void library_add_directory(const char*directory);
|
||||
class SubprogramHeader;
|
||||
class VType;
|
||||
|
||||
void library_set_work_path(const char*work_path);
|
||||
void library_add_directory(const char*directory);
|
||||
|
||||
int elaborate_libraries(void);
|
||||
int emit_packages(void);
|
||||
|
||||
extern SubprogramHeader*library_find_subprogram(perm_string name);
|
||||
SubprogramHeader*library_match_subprogram(perm_string name, const list<const VType*>*params);
|
||||
|
||||
#endif /* IVL_library_H */
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
# include "parse_misc.h"
|
||||
# include "std_types.h"
|
||||
# include "ivl_assert.h"
|
||||
# include <list>
|
||||
# include <iterator>
|
||||
|
||||
Package::Package(perm_string n, const ActiveScope&ref)
|
||||
: Scope(ref), name_(n)
|
||||
|
|
@ -45,9 +47,14 @@ int Package::elaborate()
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
errors += cur->second->elaborate();
|
||||
for (map<perm_string,SubHeaderList>::iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++ cur) {
|
||||
SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
errors += (*it)->elaborate();
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
|
@ -108,10 +115,15 @@ void Package::write_to_stream(ostream&fd) const
|
|||
fd << ";" << endl;
|
||||
}
|
||||
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
cur->second->write_to_stream(fd);
|
||||
fd << ";" << endl;
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
(*it)->write_to_stream(fd);
|
||||
fd << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = old_components_.begin()
|
||||
|
|
@ -128,14 +140,20 @@ void Package::write_to_stream(ostream&fd) const
|
|||
fd << "end package " << name_ << ";" << endl;
|
||||
|
||||
fd << "package body " << name_ << " is" << endl;
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
SubprogramHeader*subp = cur->second;
|
||||
if(subp->body()) {
|
||||
subp->write_to_stream(fd);
|
||||
fd << " is" << endl;
|
||||
subp->body()->write_to_stream(fd);
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
const SubprogramHeader*subp = *it;
|
||||
|
||||
if(subp->body()) {
|
||||
subp->write_to_stream(fd);
|
||||
fd << " is" << endl;
|
||||
subp->body()->write_to_stream(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fd << "end " << name_ << ";" << endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@
|
|||
|
||||
# include "package.h"
|
||||
# include "subprogram.h"
|
||||
# include <iostream>
|
||||
# include "ivl_assert.h"
|
||||
# include <iostream>
|
||||
# include <list>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -64,14 +65,22 @@ int Package::emit_package(ostream&fd) const
|
|||
//}
|
||||
|
||||
fd << "package \\" << name() << " ;" << endl;
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++ cur) {
|
||||
// Do not emit unbounded functions, we will just need fixed instances later
|
||||
if(!cur->second->unbounded())
|
||||
errors += cur->second->emit_package(fd);
|
||||
else
|
||||
fd << "/* function " << cur->second->name() <<
|
||||
" has to be instantiated, skipping */" << endl;
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
SubprogramHeader*header = *it;
|
||||
|
||||
// Do not emit unbounded functions, we will just need fixed instances later
|
||||
if(!header->unbounded())
|
||||
errors += header->emit_package(fd);
|
||||
else
|
||||
fd << "/* function " << header->name()
|
||||
<< " has to be instantiated, skipping */" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fd << "endpackage /* " << name() << " */" << endl;
|
||||
|
|
|
|||
|
|
@ -1701,7 +1701,8 @@ name /* IEEE 1076-2008 P8.1 */
|
|||
tmp = parse_char_enums($1);
|
||||
if(!tmp) {
|
||||
perm_string name = lex_strings.make($1);
|
||||
if(active_scope->find_subprogram(name) && !parse_type_by_name(name))
|
||||
/* There are functions that have the same name types, e.g. integer */
|
||||
if(!active_scope->find_subprogram(name).empty() && !parse_type_by_name(name))
|
||||
tmp = new ExpFunc(name);
|
||||
else
|
||||
tmp = new ExpName(name);
|
||||
|
|
@ -2565,12 +2566,10 @@ subprogram_body /* IEEE 1076-2008 P4.3 */
|
|||
K_begin subprogram_statement_part K_end
|
||||
subprogram_kind_opt identifier_opt ';'
|
||||
{ SubprogramHeader*prog = $1;
|
||||
SubprogramHeader*tmp = active_scope->recall_subprogram(prog->name());
|
||||
if (tmp && prog->compare_specification(tmp)) {
|
||||
SubprogramHeader*tmp = active_scope->recall_subprogram(prog);
|
||||
if (tmp) {
|
||||
delete prog;
|
||||
prog = tmp;
|
||||
} else if (tmp) {
|
||||
errormsg(@1, "Subprogram specification for %s doesn't match specification in package header.\n", prog->name().str());
|
||||
}
|
||||
|
||||
SubprogramBody*body = new SubprogramBody();
|
||||
|
|
|
|||
131
vhdlpp/scope.cc
131
vhdlpp/scope.cc
|
|
@ -70,9 +70,14 @@ ScopeBase::ScopeBase(const ActiveScope&ref)
|
|||
// 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.
|
||||
for (map<perm_string,SubprogramHeader*>::iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end(); ++cur) {
|
||||
cur->second->set_parent(this);
|
||||
for (map<perm_string,SubHeaderList>::iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end(); ++cur) {
|
||||
SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for (SubHeaderList::iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
(*it)->set_parent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +99,10 @@ void ScopeBase::cleanup()
|
|||
delete_all(new_components_);
|
||||
delete_all(cur_types_);
|
||||
delete_all(cur_constants_);
|
||||
delete_all(cur_subprograms_);
|
||||
for (map<perm_string,SubHeaderList>::iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end() ; ++cur) {
|
||||
delete_all(cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
const VType*ScopeBase::find_type(perm_string by_name)
|
||||
|
|
@ -157,32 +165,42 @@ const InterfacePort* ScopeBase::find_param(perm_string) const
|
|||
|
||||
const InterfacePort* ScopeBase::find_param_all(perm_string by_name) const
|
||||
{
|
||||
for(map<perm_string,SubprogramHeader*>::const_iterator it = use_subprograms_.begin();
|
||||
it != use_subprograms_.end(); ++it) {
|
||||
if(const InterfacePort*port = it->second->find_param(by_name))
|
||||
return port;
|
||||
for(map<perm_string,SubHeaderList>::const_iterator cur = use_subprograms_.begin();
|
||||
cur != use_subprograms_.end(); ++cur) {
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
if(const InterfacePort*port = (*it)->find_param(by_name))
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
for(map<perm_string,SubprogramHeader*>::const_iterator it = cur_subprograms_.begin();
|
||||
it != cur_subprograms_.end(); ++it) {
|
||||
if(const InterfacePort*port = it->second->find_param(by_name))
|
||||
return port;
|
||||
for(map<perm_string,SubHeaderList>::const_iterator cur = cur_subprograms_.begin();
|
||||
cur != cur_subprograms_.end(); ++cur) {
|
||||
const SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for(SubHeaderList::const_iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
if(const InterfacePort*port = (*it)->find_param(by_name))
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SubprogramHeader* ScopeBase::find_subprogram(perm_string name) const
|
||||
SubHeaderList ScopeBase::find_subprogram(perm_string name) const
|
||||
{
|
||||
map<perm_string,SubprogramHeader*>::const_iterator cur;
|
||||
map<perm_string,SubHeaderList>::const_iterator cur;
|
||||
|
||||
cur = cur_subprograms_.find(name);
|
||||
if (cur != cur_subprograms_.end())
|
||||
return cur->second;
|
||||
return cur->second;
|
||||
|
||||
cur = use_subprograms_.find(name);
|
||||
if (cur != use_subprograms_.end())
|
||||
return cur->second;
|
||||
return cur->second;
|
||||
|
||||
return find_std_subprogram(name);
|
||||
}
|
||||
|
|
@ -217,9 +235,9 @@ void ScopeBase::do_use_from(const ScopeBase*that)
|
|||
old_components_[cur->first] = cur->second;
|
||||
}
|
||||
|
||||
for (map<perm_string,SubprogramHeader*>::const_iterator cur = that->cur_subprograms_.begin()
|
||||
for (map<perm_string,SubHeaderList>::const_iterator cur = that->cur_subprograms_.begin()
|
||||
; cur != that->cur_subprograms_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
if (cur->second.empty())
|
||||
continue;
|
||||
use_subprograms_[cur->first] = cur->second;
|
||||
}
|
||||
|
|
@ -266,21 +284,86 @@ void ScopeBase::transfer_from(ScopeBase&ref, transfer_type_t what)
|
|||
}
|
||||
}
|
||||
|
||||
SubprogramHeader*ScopeBase::match_subprogram(perm_string name,
|
||||
const list<const VType*>*params) const
|
||||
{
|
||||
int req_param_count = params ? params->size() : 0;
|
||||
|
||||
// Find all subprograms with matching name
|
||||
SubHeaderList l = find_std_subprogram(name);
|
||||
map<perm_string,SubHeaderList>::const_iterator cur;
|
||||
|
||||
cur = use_subprograms_.find(name);
|
||||
if (cur != use_subprograms_.end())
|
||||
copy(cur->second.begin(), cur->second.end(),
|
||||
front_insert_iterator<SubHeaderList>(l));
|
||||
|
||||
cur = cur_subprograms_.find(name);
|
||||
if(cur != cur_subprograms_.end())
|
||||
copy(cur->second.begin(), cur->second.end(),
|
||||
front_insert_iterator<SubHeaderList>(l));
|
||||
|
||||
// Find the matching one
|
||||
for(SubHeaderList::iterator it = l.begin(); it != l.end(); ++it) {
|
||||
SubprogramHeader*subp = *it;
|
||||
|
||||
if(req_param_count != subp->param_count())
|
||||
continue;
|
||||
|
||||
// Do not check the return type here, it might depend on the arguments
|
||||
|
||||
if(params) {
|
||||
list<const VType*>::const_iterator p = params->begin();
|
||||
bool ok = true;
|
||||
|
||||
for(int i = 0; i < req_param_count; ++i) {
|
||||
const VType*param_type = subp->peek_param_type(i);
|
||||
|
||||
if(*p && param_type && !param_type->type_match(*p)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
continue; // check another function
|
||||
}
|
||||
|
||||
// Yay, we have a match!
|
||||
return subp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ActiveScope::set_package_header(Package*pkg)
|
||||
{
|
||||
assert(package_header_ == 0);
|
||||
package_header_ = pkg;
|
||||
}
|
||||
|
||||
SubprogramHeader* ActiveScope::recall_subprogram(perm_string name) const
|
||||
SubprogramHeader* ActiveScope::recall_subprogram(const SubprogramHeader*subp) const
|
||||
{
|
||||
if (SubprogramHeader*tmp = find_subprogram(name))
|
||||
return tmp;
|
||||
list<const VType*> arg_types;
|
||||
SubprogramHeader*tmp;
|
||||
|
||||
if (package_header_)
|
||||
return package_header_->find_subprogram(name);
|
||||
for(int i = 0; i < subp->param_count(); ++i)
|
||||
arg_types.push_back(subp->peek_param_type(i));
|
||||
|
||||
return 0;
|
||||
if ((tmp = match_subprogram(subp->name(), &arg_types))) {
|
||||
assert(!tmp->body());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (package_header_) {
|
||||
tmp = package_header_->match_subprogram(subp->name(), &arg_types);
|
||||
assert(!tmp || !tmp->body());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ActiveScope::is_vector_name(perm_string name) const
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ class SubprogramHeader;
|
|||
class VType;
|
||||
class SequentialStmt;
|
||||
|
||||
typedef list<SubprogramHeader*> SubHeaderList;
|
||||
|
||||
template<typename T>
|
||||
struct delete_object{
|
||||
void operator()(T* item) { delete item; }
|
||||
|
|
@ -59,7 +61,7 @@ class ScopeBase {
|
|||
Variable* find_variable(perm_string by_name) const;
|
||||
virtual const InterfacePort* find_param(perm_string by_name) const;
|
||||
const InterfacePort* find_param_all(perm_string by_name) const;
|
||||
SubprogramHeader* find_subprogram(perm_string by_name) const;
|
||||
SubHeaderList find_subprogram(perm_string by_name) const;
|
||||
// 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;
|
||||
|
|
@ -70,10 +72,10 @@ class ScopeBase {
|
|||
void transfer_from(ScopeBase&ref, transfer_type_t what = ALL);
|
||||
|
||||
inline void bind_subprogram(perm_string name, SubprogramHeader*obj)
|
||||
{ map<perm_string, SubprogramHeader*>::iterator it;
|
||||
{ map<perm_string, SubHeaderList>::iterator it;
|
||||
if((it = use_subprograms_.find(name)) != use_subprograms_.end() )
|
||||
use_subprograms_.erase(it);
|
||||
cur_subprograms_[name] = obj;
|
||||
it->second.remove(obj);
|
||||
cur_subprograms_[name].push_back(obj);
|
||||
}
|
||||
|
||||
// Adds a statement to implicit initializers list
|
||||
|
|
@ -92,6 +94,10 @@ class ScopeBase {
|
|||
|
||||
void dump_scope(ostream&out) const;
|
||||
|
||||
// Looks for a subprogram with specified name and parameter types.
|
||||
SubprogramHeader*match_subprogram(perm_string name,
|
||||
const list<const VType*>*params) const;
|
||||
|
||||
protected:
|
||||
void cleanup();
|
||||
|
||||
|
|
@ -134,8 +140,8 @@ class ScopeBase {
|
|||
std::map<perm_string, struct const_t*> use_constants_; //imported constants
|
||||
std::map<perm_string, struct const_t*> cur_constants_; //current constants
|
||||
|
||||
std::map<perm_string, SubprogramHeader*> use_subprograms_; //imported
|
||||
std::map<perm_string, SubprogramHeader*> cur_subprograms_; //current
|
||||
std::map<perm_string, SubHeaderList> use_subprograms_; //imported
|
||||
std::map<perm_string, SubHeaderList> cur_subprograms_; //current
|
||||
|
||||
std::list<const VTypeEnum*> use_enums_;
|
||||
|
||||
|
|
@ -191,7 +197,7 @@ class ActiveScope : public ScopeBase {
|
|||
// Locate the subprogram by name. The subprogram body uses
|
||||
// this to locate the subprogram declaration. Note that the
|
||||
// subprogram may be in a package header.
|
||||
SubprogramHeader* recall_subprogram(perm_string name) const;
|
||||
SubprogramHeader* recall_subprogram(const SubprogramHeader*subp) const;
|
||||
|
||||
/* All bind_name function check if the given name was present
|
||||
* in previous scopes. If it is found, it is erased (but the pointer
|
||||
|
|
|
|||
|
|
@ -178,10 +178,22 @@ int ProcedureCall::elaborate(Entity*ent, ScopeBase*scope)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
def_ = scope->find_subprogram(name_);
|
||||
assert(!def_); // do not elaborate twice
|
||||
|
||||
// Create a list of argument types to find a matching subprogram
|
||||
list<const VType*> arg_types;
|
||||
if(param_list_) {
|
||||
for(list<named_expr_t*>::iterator it = param_list_->begin();
|
||||
it != param_list_->end(); ++it) {
|
||||
named_expr_t* e = *it;
|
||||
arg_types.push_back(e->expr()->probe_type(ent, scope));
|
||||
}
|
||||
}
|
||||
|
||||
def_ = scope->match_subprogram(name_, &arg_types);
|
||||
|
||||
if(!def_)
|
||||
def_ = library_find_subprogram(name_);
|
||||
def_ = library_match_subprogram(name_, &arg_types);
|
||||
|
||||
if(!def_) {
|
||||
cerr << get_fileline() << ": error: could not find procedure ";
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
#include "std_types.h"
|
||||
#include "scope.h"
|
||||
|
||||
static std::map<perm_string,SubprogramHeader*> std_subprograms;
|
||||
static std::map<perm_string,SubHeaderList> std_subprograms;
|
||||
|
||||
static inline void register_std_subprogram(SubprogramHeader*header)
|
||||
{
|
||||
std_subprograms[header->name()] = header;
|
||||
std_subprograms[header->name()].push_back(header);
|
||||
}
|
||||
|
||||
// Special case: to_integer function
|
||||
|
|
@ -356,17 +356,20 @@ void preload_std_funcs(void)
|
|||
|
||||
void delete_std_funcs()
|
||||
{
|
||||
for(std::map<perm_string,SubprogramHeader*>::iterator it = std_subprograms.begin();
|
||||
it != std_subprograms.end(); ++it) {
|
||||
delete it->second;
|
||||
for(std::map<perm_string,SubHeaderList>::iterator cur = std_subprograms.begin();
|
||||
cur != std_subprograms.end(); ++cur) {
|
||||
for(SubHeaderList::const_iterator it = cur->second.begin();
|
||||
it != cur->second.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SubprogramHeader*find_std_subprogram(perm_string name)
|
||||
SubHeaderList find_std_subprogram(perm_string name)
|
||||
{
|
||||
map<perm_string,SubprogramHeader*>::const_iterator cur = std_subprograms.find(name);
|
||||
if (cur != std_subprograms.end())
|
||||
return cur->second;
|
||||
map<perm_string,SubHeaderList>::const_iterator cur = std_subprograms.find(name);
|
||||
if(cur != std_subprograms.end())
|
||||
return cur->second;
|
||||
|
||||
return NULL;
|
||||
return SubHeaderList();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@ void preload_std_funcs();
|
|||
void delete_std_funcs();
|
||||
|
||||
// Returns subprogram header for a requested function or NULL if it does not exist.
|
||||
SubprogramHeader*find_std_subprogram(perm_string name);
|
||||
SubHeaderList find_std_subprogram(perm_string name);
|
||||
|
||||
#endif /* IVL_std_funcs_H */
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
class InterfacePort;
|
||||
class SequentialStmt;
|
||||
class VType;
|
||||
class SubprogramHeader;
|
||||
|
||||
class SubprogramBody : public LineInfo, public ScopeBase {
|
||||
|
||||
|
|
@ -73,6 +72,7 @@ class SubprogramHeader : public LineInfo {
|
|||
// matches this subprogram and that subprogram.
|
||||
bool compare_specification(SubprogramHeader*that) const;
|
||||
|
||||
int param_count() const { return ports_ ? ports_->size() : 0; }
|
||||
const InterfacePort*find_param(perm_string nam) const;
|
||||
const InterfacePort*peek_param(int idx) const;
|
||||
const VType*peek_param_type(int idx) const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue