diff options
Diffstat (limited to 'frontends/ast')
| -rw-r--r-- | frontends/ast/genrtlil.cc | 2 | ||||
| -rw-r--r-- | frontends/ast/simplify.cc | 22 | 
2 files changed, 18 insertions, 6 deletions
| diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 4c25287ad..020b4e5e8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -877,7 +877,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  			this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1;  			if (children.size() > 1)  				range = children[1]; -		} else if (id_ast->type == AST_STRUCT_ITEM) { +		} else if (id_ast->type == AST_STRUCT_ITEM || id_ast->type == AST_STRUCT) {  			AstNode *tmp_range = make_struct_member_range(this, id_ast);  			this_width = tmp_range->range_left - tmp_range->range_right + 1;  			delete tmp_range; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 000877612..565025d3a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -307,6 +307,10 @@ static int size_packed_struct(AstNode *snode, int base_offset)  		if (node->type == AST_STRUCT || node->type == AST_UNION) {  			// embedded struct or union  			width = size_packed_struct(node, base_offset + offset); +			// set range of struct +			node->range_right = base_offset + offset; +			node->range_left = base_offset + offset + width - 1; +			node->range_valid = true;  		}  		else {  			log_assert(node->type == AST_STRUCT_ITEM); @@ -493,14 +497,12 @@ static void add_members_to_scope(AstNode *snode, std::string name)  	// in case later referenced in assignments  	log_assert(snode->type==AST_STRUCT || snode->type==AST_UNION);  	for (auto *node : snode->children) { +		auto member_name = name + "." + node->str; +		current_scope[member_name] = node;  		if (node->type != AST_STRUCT_ITEM) {  			// embedded struct or union  			add_members_to_scope(node, name + "." + node->str);  		} -		else { -			auto member_name = name + "." + node->str; -			current_scope[member_name] = node; -		}  	}  } @@ -1341,6 +1343,16 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	case AST_PARAMETER:  	case AST_LOCALPARAM: +		// if parameter is implicit type which is the typename of a struct or union, +		// save information about struct in wiretype attribute +		if (children[0]->type == AST_IDENTIFIER && current_scope.count(children[0]->str) > 0) { +			auto item_node = current_scope[children[0]->str]; +			if (item_node->type == AST_STRUCT || item_node->type == AST_UNION) { +				attributes[ID::wiretype] = item_node->clone(); +				size_packed_struct(attributes[ID::wiretype], 0); +				add_members_to_scope(attributes[ID::wiretype], str); +			} +		}  		while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true)  			did_something = true;  		children[0]->detectSignWidth(width_hint, sign_hint); @@ -2018,7 +2030,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		if (name_has_dot(str, sname)) {  			if (current_scope.count(str) > 0) {  				auto item_node = current_scope[str]; -				if (item_node->type == AST_STRUCT_ITEM) { +				if (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT) {  					// structure member, rewrite this node to reference the packed struct wire  					auto range = make_struct_member_range(this, item_node);  					newNode = new AstNode(AST_IDENTIFIER, range); | 
