/*
* Copyright (c) 1999 The University of Utah and
* the Computer Systems Laboratory at the University of Utah (CSL).
*
* This file is part of Flick, the Flexible IDL Compiler Kit.
*
* Flick is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Flick is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flick; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place #330, Boston, MA 02111, USA.
*/
#include <assert.h>
#include <mom/libaoi.h>
#include <mom/compiler.h>
#include <mom/c/libcast.h>
#include <mom/c/libpres_c.h>
/* A var args version that passes down to the real one below */
int pres_function(pres_c_1 *out_pres,
tag_list *parent_tl,
cast_scoped_name current_scope_name,
cast_scoped_name fname,
int tag, ...)
{
va_list arg_addr;
int retval;
va_start( arg_addr, tag );
retval = vpres_function(out_pres, parent_tl, current_scope_name,
fname, tag, arg_addr);
va_end( arg_addr );
return( retval );
}
int vpres_function(pres_c_1 *out_pres,
tag_list *parent_tl,
cast_scoped_name current_scope_name,
cast_scoped_name fname,
int tag,
va_list arg_addr)
{
cast_scope *scope = 0;
cast_func_type cfunc_decl, cfunc_def;
cast_storage_class sc = CAST_SC_NONE;
cast_type ttype = 0, ftype = 0;
union tag_data_u data;
cast_scoped_name scname;
tag_list *tl = 0;
tag_item *ti;
char *func_kind = "";
data_channel_index decl_channel = PASSTHRU_DATA_CHANNEL;
data_channel_index impl_channel = PASSTHRU_DATA_CHANNEL;
cast_def_protection current_protection = CAST_PROT_NONE;
tag_data td;
int is_global = 0;
int model = 0;
int name_idx;
int cdef;
if( parent_tl )
tl = create_tag_list(0);
td = create_tag_data(TAG_STRING_ARRAY, 0);
scname = cast_copy_scoped_name(¤t_scope_name);
name_idx = scname.cast_scoped_name_len - 1;
cast_init_function_type(&cfunc_decl, 0);
cast_init_function_type(&cfunc_def, 0);
/* Walk through the list of tags and get anything interesting */
while( tag != PFA_TAG_DONE ) {
switch( tag ) {
case PFA_DeclChannel:
decl_channel = va_arg( arg_addr, data_channel_index );
break;
case PFA_ImplChannel:
impl_channel = va_arg( arg_addr, data_channel_index );
break;
case PFA_StorageClass:
sc = va_arg( arg_addr, cast_storage_class );
break;
case PFA_Scope:
scope = va_arg( arg_addr, cast_scope * );
break;
case PFA_ReturnType:
cfunc_decl.return_type = va_arg( arg_addr, cast_type );
cfunc_def.return_type = cfunc_decl.return_type;
break;
case PFA_Parameter: {
int param_idx;
param_idx = cast_func_add_param(&cfunc_decl);
cfunc_decl.params.params_val[param_idx].type =
va_arg( arg_addr, cast_type );
data.str = va_arg( arg_addr, char * );
cfunc_decl.params.params_val[param_idx].name =
ir_strlit(data.str);
cfunc_decl.params.params_val[param_idx].default_value =
va_arg( arg_addr, cast_init );
param_idx = cast_func_add_param(&cfunc_def);
cfunc_def.params.params_val[param_idx] =
cfunc_decl.params.params_val[param_idx];
cfunc_def.params.params_val[param_idx].default_value =
0;
append_tag_data(&td, data);
break;
}
case PFA_Spec:
cfunc_def.spec = va_arg(arg_addr, cast_func_spec);
cfunc_decl.spec = cfunc_def.spec;
break;
case PFA_Template:
ftype = cast_new_function_type(0, 0);
ttype = cast_new_template_type(ftype);
break;
case PFA_TemplateParameter: {
cast_template_param_kind tpkind;
cast_template_arg default_val;
char *name;
tpkind = va_arg( arg_addr, cast_template_param_kind );
name = va_arg( arg_addr, char * );
default_val = va_arg( arg_addr, cast_template_arg );
cast_template_add_param( &ttype->cast_type_u_u.
template_type,
tpkind,
name,
default_val );
cast_add_template_arg_array_value(
&scname.cast_scoped_name_val[name_idx].args,
cast_new_template_arg_name(
cast_new_scoped_name(name, NULL)));
break;
}
case PFA_FunctionKind:
func_kind = va_arg(arg_addr, char *);
break;
case PFA_Tag: {
tag_data_kind kind;
char *tag_name;
tag_item *ti;
tag_name = va_arg(arg_addr, char *);
kind = va_arg(arg_addr, tag_data_kind);
data = va_arg(arg_addr, union tag_data_u);
if( tl ) {
ti = add_tag(tl, tag_name, TAG_NONE);
ti->data.kind = kind;
set_tag_data(&ti->data, 0, data);
}
break;
}
case PFA_Constructor:
if( tl )
add_tag(tl, "constructor", TAG_INTEGER, 1);
break;
case PFA_Model:
model = 1;
break;
case PFA_Protection:
current_protection = va_arg(arg_addr,
cast_def_protection);
break;
case PFA_GlobalFunction:
is_global = 1;
break;
default:
panic( "PFA_ Tag %d not understood", tag );
break;
}
tag = va_arg( arg_addr, int );
}
if( tl ) {
/* Add the list of parameters to the tag list */
add_tag(tl, "parameter", TAG_STRING_ARRAY, 0)->data = td;
}
/* Add the function to the scope */
cdef = cast_add_def(scope,
fname,
sc,
CAST_FUNC_DECL,
decl_channel,
current_protection);
scope->cast_scope_val[cdef].u.cast_def_u_u.func_type = cfunc_decl;
/* Add it to the stubs_cast */
cast_add_scope_name(&scname,
fname.cast_scoped_name_val[0].name,
null_template_arg_array);
if( ttype ) {
/* If its a template than we need to add the template type */
cdef = cast_add_def(&out_pres->stubs_cast,
scname,
sc,
CAST_TYPE,
impl_channel,
current_protection);
out_pres->stubs_cast.cast_scope_val[cdef].u.
cast_def_u_u.type = ttype;
ftype->cast_type_u_u.func_type = cfunc_def;
ftype->cast_type_u_u.func_type.spec &= ~CAST_FUNC_VIRTUAL;
} else {
cdef = cast_add_def(&out_pres->stubs_cast,
scname,
sc,
CAST_FUNC_DECL,
impl_channel,
current_protection);
out_pres->stubs_cast.cast_scope_val[cdef].u.cast_def_u_u.
func_type = cfunc_def;
out_pres->stubs_cast.cast_scope_val[cdef].u.cast_def_u_u.
func_type.spec &= ~CAST_FUNC_VIRTUAL;
}
if( tl ) {
/* Record the function index in the stubs_cast */
add_tag(tl, "c_func", TAG_INTEGER, cdef);
/* Record the name used to call the function, if its static
then we need a fully scoped name */
if( (sc == CAST_SC_STATIC) || is_global )
data.scname = scname;
else
data.scname = fname;
add_tag(tl, "name", TAG_CAST_SCOPED_NAME, data.scname);
add_tag(tl, "kind", TAG_STRING, func_kind);
if( model ) {
/* The function has no unique name so we add the
tag_list to the list of "model" functions. Model
functions have similar bodies but dissimilar
names. */
if( !(ti = find_tag(parent_tl, "model_func")) ) {
ti = add_tag(parent_tl, "model_func",
TAG_TAG_LIST_ARRAY, 0);
}
data.tl = tl;
append_tag_data(&ti->data, data);
} else {
/* The function has a unique name, func_kind, so we add
the tag_list with that name and record the name in
the pres_func tag_list */
add_tag(parent_tl, func_kind, TAG_TAG_LIST, tl);
if( !(ti = find_tag(parent_tl, "pres_func")) ) {
ti = add_tag(parent_tl, "pres_func",
TAG_STRING_ARRAY, 0);
}
data.str = func_kind;
append_tag_data(&ti->data, data);
}
}
return( cdef );
}
syntax highlighted by Code2HTML, v. 0.9.1