V0.9: Cache vpi_call error messages so we can include file and line info.
This patch caches the vpi_call error messages (task/function does not exist, task being called as a function and function being called as a task). This allows us to display the file name and line number information for the invalid usage.
This commit is contained in:
parent
6d56e356b4
commit
a916f8e34e
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __compile_H
|
#ifndef __compile_H
|
||||||
#define __compile_H
|
#define __compile_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -403,6 +403,7 @@ extern void compile_vpi_func_call(char*label, char*name,
|
||||||
unsigned vbit, int vwid,
|
unsigned vbit, int vwid,
|
||||||
long file_idx, long lineno,
|
long file_idx, long lineno,
|
||||||
unsigned argc, vpiHandle*argv);
|
unsigned argc, vpiHandle*argv);
|
||||||
|
extern void print_vpi_call_errors();
|
||||||
|
|
||||||
extern void compile_fork(char*label, struct symb_s targ_s,
|
extern void compile_fork(char*label, struct symb_s targ_s,
|
||||||
struct symb_s scope_s);
|
struct symb_s scope_s);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -276,7 +276,7 @@ int main(int argc, char*argv[])
|
||||||
if (version_flag) {
|
if (version_flag) {
|
||||||
fprintf(stderr, "Icarus Verilog runtime version " VERSION " ("
|
fprintf(stderr, "Icarus Verilog runtime version " VERSION " ("
|
||||||
VERSION_TAG ")\n\n");
|
VERSION_TAG ")\n\n");
|
||||||
fprintf(stderr, "Copyright 1998-2009 Stephen Williams\n\n");
|
fprintf(stderr, "Copyright 1998-2010 Stephen Williams\n\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" This program is free software; you can redistribute it and/or modify\n"
|
" This program is free software; you can redistribute it and/or modify\n"
|
||||||
" it under the terms of the GNU General Public License as published by\n"
|
" it under the terms of the GNU General Public License as published by\n"
|
||||||
|
|
@ -345,6 +345,7 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
int ret_cd = compile_design(design_path);
|
int ret_cd = compile_design(design_path);
|
||||||
destroy_lexor();
|
destroy_lexor();
|
||||||
|
print_vpi_call_errors();
|
||||||
if (ret_cd) return ret_cd;
|
if (ret_cd) return ret_cd;
|
||||||
|
|
||||||
if (!have_ivl_version) {
|
if (!have_ivl_version) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -547,6 +547,67 @@ struct __vpiUserSystf* vpip_find_systf(const char*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To get better error message we need to cache the vpi_call fail
|
||||||
|
* information so that we can print the file name.
|
||||||
|
*/
|
||||||
|
enum vpi_call_error_type {VPI_CALL_NO_DEF, VPI_CALL_TASK_AS_FUNC,
|
||||||
|
VPI_CALL_FUNC_AS_TASK};
|
||||||
|
typedef struct vpi_call_error {
|
||||||
|
vpi_call_error_type type;
|
||||||
|
char *name;
|
||||||
|
long file_idx;
|
||||||
|
long lineno;
|
||||||
|
} vpi_call_error_s, *vpi_call_error_p;
|
||||||
|
|
||||||
|
static vpi_call_error_p vpi_call_error_lst = NULL;
|
||||||
|
static unsigned vpi_call_error_num = 0;
|
||||||
|
|
||||||
|
static void add_vpi_call_error(vpi_call_error_type type, const char *name,
|
||||||
|
long file_idx, long lineno)
|
||||||
|
{
|
||||||
|
vpi_call_error_lst = (vpi_call_error_p)
|
||||||
|
realloc((void *)vpi_call_error_lst,
|
||||||
|
(vpi_call_error_num + 1) *
|
||||||
|
sizeof(vpi_call_error_s));
|
||||||
|
vpi_call_error_lst[vpi_call_error_num].type = type;
|
||||||
|
vpi_call_error_lst[vpi_call_error_num].name = strdup(name);
|
||||||
|
vpi_call_error_lst[vpi_call_error_num].file_idx = file_idx;
|
||||||
|
vpi_call_error_lst[vpi_call_error_num].lineno = lineno;
|
||||||
|
vpi_call_error_num += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vpi_call_errors()
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0; idx < vpi_call_error_num; idx += 1) {
|
||||||
|
switch (vpi_call_error_lst[idx].type) {
|
||||||
|
case VPI_CALL_NO_DEF:
|
||||||
|
fprintf(stderr, "%s:%d: Error: System task/function %s() is "
|
||||||
|
"not defined by any module.\n",
|
||||||
|
file_names[vpi_call_error_lst[idx].file_idx],
|
||||||
|
vpi_call_error_lst[idx].lineno,
|
||||||
|
vpi_call_error_lst[idx].name);
|
||||||
|
break;
|
||||||
|
case VPI_CALL_TASK_AS_FUNC:
|
||||||
|
fprintf(stderr, "%s:%d: Error: %s() is a system task, it "
|
||||||
|
"cannot be called as a function.\n",
|
||||||
|
file_names[vpi_call_error_lst[idx].file_idx],
|
||||||
|
vpi_call_error_lst[idx].lineno,
|
||||||
|
vpi_call_error_lst[idx].name);
|
||||||
|
break;
|
||||||
|
case VPI_CALL_FUNC_AS_TASK:
|
||||||
|
fprintf(stderr, "%s:%d: Error: %s() is a system function, it "
|
||||||
|
"cannot be called as a task.\n",
|
||||||
|
file_names[vpi_call_error_lst[idx].file_idx],
|
||||||
|
vpi_call_error_lst[idx].lineno,
|
||||||
|
vpi_call_error_lst[idx].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(vpi_call_error_lst[idx].name);
|
||||||
|
}
|
||||||
|
free(vpi_call_error_lst);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A vpi_call is actually built up into a vpiSysTaskCall VPI object
|
* A vpi_call is actually built up into a vpiSysTaskCall VPI object
|
||||||
* that refers back to the vpiUserSystf VPI object that is the
|
* that refers back to the vpiUserSystf VPI object that is the
|
||||||
|
|
@ -566,16 +627,15 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
|
||||||
{
|
{
|
||||||
struct __vpiUserSystf*defn = vpip_find_systf(name);
|
struct __vpiUserSystf*defn = vpip_find_systf(name);
|
||||||
if (defn == 0) {
|
if (defn == 0) {
|
||||||
fprintf(stderr, "%s: This task not defined "
|
add_vpi_call_error(VPI_CALL_NO_DEF, name, file_idx, lineno);
|
||||||
"by any modules. I cannot compile it.\n", name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (defn->info.type) {
|
switch (defn->info.type) {
|
||||||
case vpiSysTask:
|
case vpiSysTask:
|
||||||
if (vwid != 0 || fnet != 0) {
|
if (vwid != 0 || fnet != 0) {
|
||||||
fprintf(stderr, "%s: This is a system Task, "
|
add_vpi_call_error(VPI_CALL_TASK_AS_FUNC, name, file_idx,
|
||||||
"you cannot call it as a Function\n", name);
|
lineno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert(vbit == 0);
|
assert(vbit == 0);
|
||||||
|
|
@ -583,14 +643,15 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
|
||||||
|
|
||||||
case vpiSysFunc:
|
case vpiSysFunc:
|
||||||
if (vwid == 0 && fnet == 0) {
|
if (vwid == 0 && fnet == 0) {
|
||||||
fprintf(stderr, "%s: This is a system Function, "
|
add_vpi_call_error(VPI_CALL_FUNC_AS_TASK, name, file_idx,
|
||||||
"you cannot call it as a Task\n", name);
|
lineno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unsupported type %d.\n", (int)defn->info.type);
|
fprintf(stderr, "Unsupported call type %d.\n",
|
||||||
|
(int)defn->info.type);
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue