Allow typedefs to override inherited type names.
This commit is contained in:
parent
bb182cf3ce
commit
a849249a86
12
lexor.lex
12
lexor.lex
|
|
@ -325,8 +325,8 @@ TU [munpf]
|
||||||
if (in_package_scope) {
|
if (in_package_scope) {
|
||||||
if (rc == IDENTIFIER) {
|
if (rc == IDENTIFIER) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
|
if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
|
||||||
delete[]yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.data_type = type;
|
yylval.type_identifier.type = type;
|
||||||
rc = TYPE_IDENTIFIER;
|
rc = TYPE_IDENTIFIER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -361,8 +361,8 @@ TU [munpf]
|
||||||
return this as a TYPE_IDENTIFIER instead. */
|
return this as a TYPE_IDENTIFIER instead. */
|
||||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||||
delete[]yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.data_type = type;
|
yylval.type_identifier.type = type;
|
||||||
rc = TYPE_IDENTIFIER;
|
rc = TYPE_IDENTIFIER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -382,8 +382,8 @@ TU [munpf]
|
||||||
}
|
}
|
||||||
if (gn_system_verilog()) {
|
if (gn_system_verilog()) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||||
delete[]yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.data_type = type;
|
yylval.type_identifier.type = type;
|
||||||
return TYPE_IDENTIFIER;
|
return TYPE_IDENTIFIER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
parse.y
51
parse.y
|
|
@ -417,6 +417,11 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
property_qualifier_t property_qualifier;
|
property_qualifier_t property_qualifier;
|
||||||
PPackage*package;
|
PPackage*package;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char*text;
|
||||||
|
data_type_t*type;
|
||||||
|
} type_identifier;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
data_type_t*type;
|
data_type_t*type;
|
||||||
list<PExpr*>*exprs;
|
list<PExpr*>*exprs;
|
||||||
|
|
@ -431,7 +436,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
};
|
};
|
||||||
|
|
||||||
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
|
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
|
||||||
%token <data_type> TYPE_IDENTIFIER
|
%token <type_identifier> TYPE_IDENTIFIER
|
||||||
%token <package> PACKAGE_IDENTIFIER
|
%token <package> PACKAGE_IDENTIFIER
|
||||||
%token <discipline> DISCIPLINE_IDENTIFIER
|
%token <discipline> DISCIPLINE_IDENTIFIER
|
||||||
%token <text> PATHPULSE_IDENTIFIER
|
%token <text> PATHPULSE_IDENTIFIER
|
||||||
|
|
@ -730,10 +735,11 @@ class_identifier
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
{ class_type_t*tmp = dynamic_cast<class_type_t*>($1);
|
{ class_type_t*tmp = dynamic_cast<class_type_t*>($1.type);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
yyerror(@1, "Type name is not a predeclared class name.");
|
yyerror(@1, "Type name \"%s\"is not a predeclared class name.", $1.text);
|
||||||
}
|
}
|
||||||
|
delete[]$1.text;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -743,13 +749,14 @@ class_identifier
|
||||||
does indeed match a name. */
|
does indeed match a name. */
|
||||||
class_declaration_endlabel_opt
|
class_declaration_endlabel_opt
|
||||||
: ':' TYPE_IDENTIFIER
|
: ':' TYPE_IDENTIFIER
|
||||||
{ class_type_t*tmp = dynamic_cast<class_type_t*> ($2);
|
{ class_type_t*tmp = dynamic_cast<class_type_t*> ($2.type);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
yyerror(@2, "error: class declaration endlabel is not a class name\n");
|
yyerror(@2, "error: class declaration endlabel \"%s\" is not a class name\n", $2.text);
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
} else {
|
} else {
|
||||||
$$ = strdupnew(tmp->name.str());
|
$$ = strdupnew(tmp->name.str());
|
||||||
}
|
}
|
||||||
|
delete[]$2.text;
|
||||||
}
|
}
|
||||||
| ':' IDENTIFIER
|
| ':' IDENTIFIER
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
|
|
@ -767,12 +774,14 @@ class_declaration_endlabel_opt
|
||||||
|
|
||||||
class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */
|
class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */
|
||||||
: K_extends TYPE_IDENTIFIER
|
: K_extends TYPE_IDENTIFIER
|
||||||
{ $$.type = $2;
|
{ $$.type = $2.type;
|
||||||
$$.exprs= 0;
|
$$.exprs= 0;
|
||||||
|
delete[]$2.text;
|
||||||
}
|
}
|
||||||
| K_extends TYPE_IDENTIFIER '(' expression_list_with_nuls ')'
|
| K_extends TYPE_IDENTIFIER '(' expression_list_with_nuls ')'
|
||||||
{ $$.type = $2;
|
{ $$.type = $2.type;
|
||||||
$$.exprs = $4;
|
$$.exprs = $4;
|
||||||
|
delete[]$2.text;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
{ $$.type = 0; $$.exprs = 0; }
|
{ $$.type = 0; $$.exprs = 0; }
|
||||||
|
|
@ -1013,14 +1022,16 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| TYPE_IDENTIFIER dimensions_opt
|
| TYPE_IDENTIFIER dimensions_opt
|
||||||
{ if ($2) $$ = new parray_type_t($1, $2);
|
{ if ($2) $$ = new parray_type_t($1.type, $2);
|
||||||
else $$ = $1;
|
else $$ = $1.type;
|
||||||
|
delete[]$1.text;
|
||||||
}
|
}
|
||||||
| PACKAGE_IDENTIFIER K_SCOPE_RES
|
| PACKAGE_IDENTIFIER K_SCOPE_RES
|
||||||
{ lex_in_package_scope($1); }
|
{ lex_in_package_scope($1); }
|
||||||
TYPE_IDENTIFIER
|
TYPE_IDENTIFIER
|
||||||
{ lex_in_package_scope(0);
|
{ lex_in_package_scope(0);
|
||||||
$$ = $4;
|
$$ = $4.type;
|
||||||
|
delete[]$4.text;
|
||||||
}
|
}
|
||||||
| K_string
|
| K_string
|
||||||
{ string_type_t*tmp = new string_type_t;
|
{ string_type_t*tmp = new string_type_t;
|
||||||
|
|
@ -2143,6 +2154,20 @@ type_declaration
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the IDENTIFIER already is a typedef, it is possible for this
|
||||||
|
code to override the definition, but only if the typedef is
|
||||||
|
inherited from a different scope. */
|
||||||
|
| K_typedef data_type TYPE_IDENTIFIER ';'
|
||||||
|
{ perm_string name = lex_strings.make($3.text);
|
||||||
|
if (pform_test_type_identifier_local(name)) {
|
||||||
|
yyerror(@3, "error: Typedef identifier \"%s\" is already a type name.", $3.text);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pform_set_typedef(name, $2);
|
||||||
|
}
|
||||||
|
delete[]$3.text;
|
||||||
|
}
|
||||||
|
|
||||||
/* These are forward declarations... */
|
/* These are forward declarations... */
|
||||||
|
|
||||||
| K_typedef K_class IDENTIFIER ';'
|
| K_typedef K_class IDENTIFIER ';'
|
||||||
|
|
@ -2170,9 +2195,6 @@ type_declaration
|
||||||
delete[]$2;
|
delete[]$2;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_typedef data_type TYPE_IDENTIFIER ';'
|
|
||||||
{ yyerror(@3, "error: Typedef identifier is already a type name."); }
|
|
||||||
|
|
||||||
| K_typedef error ';'
|
| K_typedef error ';'
|
||||||
{ yyerror(@2, "error: Syntax error in typedef clause.");
|
{ yyerror(@2, "error: Syntax error in typedef clause.");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
|
|
@ -3108,9 +3130,10 @@ expr_primary
|
||||||
/* There are a few special cases (notably $bits argument) where the
|
/* There are a few special cases (notably $bits argument) where the
|
||||||
expression may be a type name. Let the elaborator sort this out. */
|
expression may be a type name. Let the elaborator sort this out. */
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
{ PETypename*tmp = new PETypename($1);
|
{ PETypename*tmp = new PETypename($1.type);
|
||||||
FILE_NAME(tmp,@1);
|
FILE_NAME(tmp,@1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
delete[]$1.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The hierarchy_identifier rule matches simple identifiers as well as
|
/* The hierarchy_identifier rule matches simple identifiers as well as
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ extern void lex_in_package_scope(PPackage*pkg);
|
||||||
extern data_type_t* pform_test_type_identifier(const char*txt);
|
extern data_type_t* pform_test_type_identifier(const char*txt);
|
||||||
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
||||||
|
|
||||||
|
extern bool pform_test_type_identifier_local(perm_string txt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test if this identifier is a package name. The pform needs to help
|
* Test if this identifier is a package name. The pform needs to help
|
||||||
* the lexor here because the parser detects packages and saves them.
|
* the lexor here because the parser detects packages and saves them.
|
||||||
|
|
|
||||||
25
pform.cc
25
pform.cc
|
|
@ -584,6 +584,31 @@ data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The parser uses this function to test if the name is a typedef in
|
||||||
|
* the current scope. We use this to know if we can override the
|
||||||
|
* definition because it shadows a containing scope.
|
||||||
|
*/
|
||||||
|
bool pform_test_type_identifier_local(perm_string name)
|
||||||
|
{
|
||||||
|
if (lexical_scope == 0) {
|
||||||
|
if (test_type_identifier_in_root(name))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LexicalScope*cur_scope = lexical_scope;
|
||||||
|
|
||||||
|
map<perm_string,data_type_t*>::iterator cur;
|
||||||
|
|
||||||
|
cur = cur_scope->typedefs.find(name);
|
||||||
|
if (cur != cur_scope->typedefs.end())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
||||||
const pform_name_t&name,
|
const pform_name_t&name,
|
||||||
const list<PExpr*>&parms)
|
const list<PExpr*>&parms)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue