Blend implicit constructor with explicit constructor
Class types that have both implicit construction and an explicit constructor can blend the implicit and explicit construction into the "new" function defined by the user. This doesn't change the behavior any, but removes a function call and related scope.
This commit is contained in:
parent
637d43fb5a
commit
046535cfbb
2
PTask.h
2
PTask.h
|
|
@ -110,6 +110,8 @@ class PFunction : public PTaskFunc {
|
|||
void set_statement(Statement *s);
|
||||
void set_return(const data_type_t*t);
|
||||
|
||||
inline Statement* get_statement() { return statement_; }
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
/* elaborate the ports and return value. */
|
||||
|
|
|
|||
12
Statement.cc
12
Statement.cc
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
Statement::~Statement()
|
||||
{
|
||||
|
|
@ -126,6 +127,17 @@ void PBlock::set_statement(const vector<Statement*>&st)
|
|||
list_ = st;
|
||||
}
|
||||
|
||||
void PBlock::push_statement_front(Statement*that)
|
||||
{
|
||||
ivl_assert(*this, bl_type_==BL_SEQ);
|
||||
|
||||
list_.resize(list_.size()+1);
|
||||
for (size_t idx = list_.size()-1 ; idx > 0 ; idx -= 1)
|
||||
list_[idx] = list_[idx-1];
|
||||
|
||||
list_[0] = that;
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
||||
: package_(0), path_(n), parms_(p.size())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -186,6 +186,10 @@ class PBlock : public PScope, public Statement {
|
|||
|
||||
void set_statement(const std::vector<Statement*>&st);
|
||||
|
||||
// Copy the statement from that block to the front of this
|
||||
// block.
|
||||
void push_statement_front(Statement*that);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
|
|
|||
|
|
@ -293,8 +293,60 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_class(Design*des, NetScope*scope,
|
||||
PClass*pclass)
|
||||
/*
|
||||
* If the pclass includes an implicit and explicit constructor, then
|
||||
* merge the implicit constructor into the explicit constructor as
|
||||
* statements in the beginning.
|
||||
*
|
||||
* This is not necessary for proper functionality, it is an
|
||||
* optimization, so we can easily give up if it doesn't seem like it
|
||||
* will obviously work.
|
||||
*/
|
||||
static void blend_class_constructors(PClass*pclass)
|
||||
{
|
||||
perm_string new1 = perm_string::literal("new");
|
||||
perm_string new2 = perm_string::literal("new@");
|
||||
|
||||
map<perm_string,PFunction*>::iterator iter_new = pclass->funcs.find(new1);
|
||||
if (iter_new == pclass->funcs.end())
|
||||
return;
|
||||
|
||||
map<perm_string,PFunction*>::iterator iter_new2 = pclass->funcs.find(new2);
|
||||
if (iter_new2 == pclass->funcs.end())
|
||||
return;
|
||||
|
||||
PFunction*use_new = iter_new->second;
|
||||
PFunction*use_new2 = iter_new2->second;
|
||||
|
||||
// These constructors must be methods of the same class.
|
||||
ivl_assert(*use_new, use_new->method_of() == use_new2->method_of());
|
||||
|
||||
Statement*def_new = use_new->get_statement();
|
||||
Statement*def_new2 = use_new2->get_statement();
|
||||
|
||||
// If either constructor has no definition, then give up. This
|
||||
// might happen, for example, during parse errors or other
|
||||
// degenerate situations.
|
||||
if (def_new==0 || def_new2==0)
|
||||
return;
|
||||
|
||||
PBlock*blk_new = dynamic_cast<PBlock*> (def_new);
|
||||
|
||||
// For now, only do this if the functions are defined by
|
||||
// statement blocks. That should be true by definition for
|
||||
// implicit constructors, and common for explicit constructors.
|
||||
if (blk_new==0)
|
||||
return;
|
||||
|
||||
ivl_assert(*blk_new, blk_new ->bl_type()==PBlock::BL_SEQ);
|
||||
|
||||
blk_new->push_statement_front(def_new2);
|
||||
|
||||
pclass->funcs.erase(iter_new2);
|
||||
delete use_new2;
|
||||
}
|
||||
|
||||
static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
{
|
||||
class_type_t*use_type = pclass->type;
|
||||
netclass_t*use_class = new netclass_t(use_type->name);
|
||||
|
|
@ -367,8 +419,10 @@ static void elaborate_scope_class(Design*des, NetScope*scope,
|
|||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
const vector<PClass*>&classes)
|
||||
{
|
||||
for (size_t idx = 0 ; idx < classes.size() ; idx += 1)
|
||||
for (size_t idx = 0 ; idx < classes.size() ; idx += 1) {
|
||||
blend_class_constructors(classes[idx]);
|
||||
elaborate_scope_class(des, scope, classes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||
|
|
|
|||
Loading…
Reference in New Issue