diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 3454c7772..5104e502a 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -625,16 +625,7 @@ int ExpFunc::emit(ostream&out, Entity*ent, ScopeBase*scope) const return 1; } - // If this function has an elaborated definition, and if - // that definition is in a package, then include the - // package name as a scope qualifier. This assures that - // the SV elaborator finds the correct VHDL elaborated - // definition. - const Package*pkg = dynamic_cast (def_->get_parent()); - if (pkg != 0) - out << "\\" << pkg->name() << " ::"; - - errors += def_->emit_name(argv_, out, ent, scope); + def_->emit_full_name(argv_, out, ent, scope); out << " ("; def_->emit_args(argv_, out, ent, scope); out << ")"; diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index 2a417d2eb..c0d7b67f1 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -210,26 +210,27 @@ void VariableSeqAssignment::write_to_stream(ostream&fd) int ProcedureCall::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; - std::vectorparams; + vectorargv; + if(!def_) { + cerr << get_fileline() << ": error: unknown procedure: " << name_ << endl; + return 1; + } + + // Convert the parameter list to vector if(param_list_) { - params.reserve(param_list_->size()); + argv.reserve(param_list_->size()); for(std::list::iterator it = param_list_->begin(); it != param_list_->end(); ++it) - params.push_back((*it)->expr()); + argv.push_back((*it)->expr()); } - const Package*pkg = dynamic_cast (def_->get_parent()); - if (pkg != 0) - out << "\\" << pkg->name() << " ::"; - - errors += def_->emit_name(params, out, ent, scope); - + def_->emit_full_name(argv, out, ent, scope); out << " ("; - if(param_list_) { - errors += def_->emit_args(params, out, ent, scope); - } + + if(param_list_) + errors += def_->emit_args(argv, out, ent, scope); out << ");" << endl; return errors; diff --git a/vhdlpp/subprogram.h b/vhdlpp/subprogram.h index c8898f86f..f5bdbb3ec 100644 --- a/vhdlpp/subprogram.h +++ b/vhdlpp/subprogram.h @@ -94,11 +94,15 @@ class SubprogramHeader : public LineInfo { int elaborate() { return (body_ ? body_->elaborate() : 0); } + // Emits the function name, including the package if required. + int emit_full_name(const std::vector&argv, + std::ostream&out, Entity*, ScopeBase*) const; + // Function name used in the emission step. The main purpose of this // method is to handle functions offered by standard VHDL libraries. // Allows to return different function names depending on the arguments // (think of size casting or signed/unsigned functions). - virtual int emit_name(const std::vector&, + virtual int emit_name(const std::vector&argv, std::ostream&out, Entity*, ScopeBase*) const; // Emit arguments for a specific call. It allows to reorder or skip diff --git a/vhdlpp/subprogram_emit.cc b/vhdlpp/subprogram_emit.cc index 907550475..18ab855a3 100644 --- a/vhdlpp/subprogram_emit.cc +++ b/vhdlpp/subprogram_emit.cc @@ -21,6 +21,7 @@ # include "subprogram.h" # include "sequential.h" # include "vtype.h" +# include "package.h" # include using namespace std; @@ -97,6 +98,23 @@ int SubprogramHeader::emit_package(ostream&fd) const return errors; } +int SubprogramHeader::emit_full_name(const std::vector&argv, + std::ostream&out, Entity*ent, ScopeBase*scope) const +{ + // If this function has an elaborated definition, and if + // that definition is in a package, then include the + // package name as a scope qualifier. This assures that + // the SV elaborator finds the correct VHDL elaborated + // definition. It should not be emitted only if we call another + // function from the same package. + const Package*pkg = dynamic_cast(parent_); + const SubprogramBody*subp = dynamic_cast(scope); + if (pkg != 0 && (!subp || !subp->header() || subp->header()->get_parent() != pkg)) + out << "\\" << pkg->name() << " ::"; + + return emit_name(argv, out, ent, scope); +} + int SubprogramHeader::emit_name(const std::vector&, std::ostream&out, Entity*, ScopeBase*) const {