/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#ifndef VBOX
#include <strings.h>
#include <stdlib.h>
#include <limits.h>
#include <alloca.h>
#include <assert.h>
#endif
#include <dt_decl.h>
#include <dt_parser.h>
#include <dt_module.h>
#include <dt_impl.h>
static dt_decl_t *
{
return (ddp); /* nothing to check if the type is not yet set */
"long may not be used with char type\n");
}
(DT_DA_SIGNED | DT_DA_UNSIGNED)))) {
"may not be used with void type\n");
}
"unsigned may only be used with integer type\n");
}
"long long may only be used with integer or "
"floating-point type\n");
}
return (ddp);
}
{
return (ddp);
}
void
{
}
}
void
dt_decl_reset(void)
{
}
}
{
(void) dt_decl_check(top);
}
return (ddp);
}
dt_decl_pop(void)
{
return (ddp);
}
{
"for function or associative array parameter\n");
}
}
return (dt_decl_pop());
}
dt_decl_top(void)
{
(void) dt_decl_check(ddp);
}
return (ddp);
}
{
"incorrect type specified\n");
}
return (ddp);
}
void
{
"in a declaration\n");
}
}
/*
* Set the kind and name of the current declaration. If none is allocated,
* make a new decl and push it on to the top of our stack. If the name or kind
* is already set for the current decl, then we need to fail this declaration.
* This can occur because too many types were given (e.g. "int int"), etc.
*/
{
/*
* If we already have a type name specified and we see another type
* name, this is an error if the declaration is a typedef. If the
* declaration is not a typedef, then the user may be trying to declare
* a variable whose name has been returned by lex as a TNAME token:
* call dt_decl_ident() as if the grammar's IDENT rule was matched.
*/
return (dt_decl_ident(name));
}
"in a type name\n");
}
return (dt_decl_check(ddp));
}
{
return (ddp);
}
}
return (dt_decl_check(ddp));
}
/*
* Examine the list of formal parameters 'flist' and determine if the formal
* name fnp->dn_string is defined in this list (B_TRUE) or not (B_FALSE).
* If 'fnp' is in 'flist', do not search beyond 'fnp' itself in 'flist'.
*/
static int
{
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Common code for parsing array, function, and probe definition prototypes.
* The prototype node list is specified as 'plist'. The formal prototype
* against which to compare the prototype is specified as 'flist'. If plist
* and flist are the same, we require that named parameters are unique. If
* plist and flist are different, we require that named parameters in plist
* match a name that is present in flist.
*/
int
{
char n[DT_TYPE_NAMELEN];
"not use a variable-length argument list\n", kind);
}
"use parameter of type %s: %s, parameter #%d\n",
}
v += is_void;
"use parameter of type %s: %s, parameter #%d\n",
}
}
"%s declared in %s prototype: %s, parameter #%d\n",
}
"requires a name: parameter #%d\n", i);
}
}
return (v ? 0 : i - 1); /* return zero if sole parameter is 'void' */
}
{
/*
* After pushing the array on to the decl stack, scan ahead for multi-
* dimensional array declarations and push the current decl to the
* bottom to match the resulting CTF type tree and data layout. Refer
* to the comments in dt_decl_type() and ISO C 6.5.2.1 for more info.
*/
"cannot declare array of associative arrays\n");
}
}
if (dt_node_is_posconst(dnp) == 0) {
"expression or tuple signature expected as "
"array declaration subscript\n");
}
}
return (ddp);
}
/*
* When a function is declared, we need to fudge the decl stack a bit if the
* declaration uses the function pointer (*)() syntax. In this case, the
* dt_decl_func() call occurs *after* the dt_decl_ptr() call, even though the
* resulting type is "pointer to function". To make the pointer land on top,
* we check to see if 'pdp' is non-NULL and a pointer. If it is, we search
* backward for a decl tagged with DT_DA_PAREN, and if one is found, the func
* decl is inserted behind this node in the decl list instead of at the top.
* In all cases, the func decl's dd_next pointer is set to the decl chain
* for the function's return type and the function parameter list is discarded.
*/
{
return (dt_decl_push(ddp));
return (dt_decl_push(ddp));
return (pdp);
}
dt_decl_ptr(void)
{
}
{
char n[DT_TYPE_NAMELEN];
if (yypcb->pcb_idepth != 0)
else
else
flag = CTF_ADD_ROOT;
(void) snprintf(n, sizeof (n), "%s %s",
if (kind == CTF_K_STRUCT)
else
}
return (ddp);
}
void
{
char n[DT_TYPE_NAMELEN];
(void) dt_decl_check(ddp);
}
"in a member name (%s)\n", ident);
}
"cannot have dynamic member: %s\n", ident);
}
n, sizeof (n)), ident);
}
if (size == 0)
/*
* If a bit-field qualifier was part of the member declaration, create
* a new integer type of the same name and attributes as the base type
* and size equal to the specified number of bits. We reset 'dtt' to
* refer to this new bit-field type and continue on to add the member.
*/
/*
* A bit-field member with no declarator is permitted to have
* size zero and indicates that no more fields are to be packed
* into the current storage unit. We ignore these directives
* as the underlying ctf code currently does so for all fields.
*/
goto done;
}
if (dt_node_is_posconst(dnp) == 0) {
"expression expected as bit-field size\n");
}
"bit-field: %s\n", idname);
}
"for type: %s\n", idname);
}
cte.cte_offset = 0;
"member '%s': %s\n", idname,
}
}
/*
* If the member type is not defined in the same CTF container as the
* one associated with the current scope (i.e. the container for the
* struct or union itself) or its parent, copy the member type into
* this container and reset dtt to refer to the copied type.
*/
}
}
}
done:
free(ident);
}
/*ARGSUSED*/
static int
{
return (1); /* abort search and return true if a member exists */
}
{
char n[DT_TYPE_NAMELEN];
if (yypcb->pcb_idepth != 0)
else
else
flag = CTF_ADD_ROOT;
}
return (ddp);
}
void
{
char *name;
int value;
#ifndef VBOX
#else
MY_STRDUPA(name, s);
#endif
free(s);
"an enumerator name (%s)\n", name);
}
/*
* If the enumerator is being assigned a value, cook and check the node
* and then free it after we get the value. We also permit references
* to identifiers which are previously defined enumerators in the type.
*/
"be assigned to an integral constant "
"expression\n", name);
}
}
}
}
}
/*
* If the enumerator name matches an identifier in the global scope,
* flag this as an error. We only do this for "D" enumerators to
* prevent "C" header file enumerators from conflicting with the ever-
* growing list of D built-in global variables and inlines. If a "C"
* enumerator conflicts with a global identifier, we add the enumerator
* but do not insert a corresponding inline (i.e. the D variable wins).
*/
"identifier redeclared: %s\n", name);
} else
return;
}
yyintprefix = 0;
yyintsuffix[0] = '\0';
yyintdecimal = 0;
/*
* Remove the INT node from the node allocation list and store it in
* din_list and din_root so it persists with and is freed by the ident.
*/
}
/*
* Look up the type corresponding to the specified decl stack. The scoping of
* the underlying type names is handled by dt_type_lookup(). We build up the
* name from the specified string and prefixes and then lookup the type. If
* we fail, an errmsg is saved and the caller must abort with EDT_COMPILER.
*/
int
{
ctf_arinfo_t r;
char n[DT_TYPE_NAMELEN];
char *name;
int rv;
/*
* Based on our current #include depth and decl stack depth, determine
* which dynamic CTF module and scope to use when adding any new types.
*/
/*
* If we have already cached a CTF type for this decl, then we just
* return the type information for the cached type.
*/
return (0);
}
/*
* Currently CTF treats all function pointers identically. We cache a
* representative ID of kind CTF_K_FUNCTION and just return that type.
* If we want to support full function declarations, dd_next refers to
* the declaration of the function return type, and the parameter list
* should be parsed and hung off a new pointer inside of this decl.
*/
return (0);
}
/*
* If the decl is a pointer, resolve the rest of the stack by calling
* dt_decl_type() recursively and then compute a pointer to the result.
* Similar to the code above, we return a cached id for function ptrs.
*/
return (0);
}
}
return (rv);
}
/*
* If the decl is an array, we must find the base type and then call
* dt_decl_type() recursively and then build an array of the result.
* The C and D multi-dimensional array syntax requires that consecutive
* array declarations be processed from right-to-left (i.e. top-down
* from the perspective of the declaration stack). For example, an
* array declaration such as int x[3][5] is stored on the stack as:
*
* (bottom) NULL <- ( INT "int" ) <- ( ARR [3] ) <- ( ARR [5] ) (top)
*
* but means that x is declared to be an array of 3 objects each of
* which is an array of 5 integers, or in CTF representation:
*
* type T1:( content=int, nelems=5 ) type T2:( content=T1, nelems=3 )
*
* For more details, refer to K&R[5.7] and ISO C 6.5.2.1. Rather than
* overcomplicate the implementation of dt_decl_type(), we push array
* declarations down into the stack in dt_decl_array(), above, so that
* by the time dt_decl_type() is called, the decl stack looks like:
*
* (bottom) NULL <- ( INT "int" ) <- ( ARR [5] ) <- ( ARR [3] ) (top)
*
* which permits a straightforward recursive descent of the decl stack
* to build the corresponding CTF type tree in the appropriate order.
*/
/*
* If the array decl has a parameter list associated with it,
* this is an associative array declaration: return <DYN>.
*/
return (0);
}
return (rv);
/*
* If the array base type is not defined in the target
* container or its parent, copy the type to the target
* container and reset dtt_ctfp and dtt_type to the copy.
*/
return (-1);
}
}
/*
* The array index type is irrelevant in C and D: just set it
* to "long" for all array types that we create on-the-fly.
*/
return (-1);
}
return (0);
}
/*
* Allocate space for the type name and enough space for the maximum
* additional text ("unsigned long long \0" requires 20 more bytes).
*/
name[0] = '\0';
case CTF_K_INTEGER:
case CTF_K_FLOAT:
break;
case CTF_K_STRUCT:
break;
case CTF_K_UNION:
break;
case CTF_K_ENUM:
break;
case CTF_K_TYPEDEF:
break;
default:
return (-1);
}
/*
* Add dd_name unless a short, long, or long long is explicitly
*/
/*
* Lookup the type. If we find it, we're done. Otherwise create a
* forward tag for the type if it is a struct, union, or enum. If
* we can't find it and we can't create a tag, return failure.
*/
return (rv);
case CTF_K_STRUCT:
case CTF_K_UNION:
case CTF_K_ENUM:
break;
default:
return (rv);
}
return (-1);
}
return (0);
}
void
{
}
void
{
}
}
void
{
}
dt_scope_pop(void)
{
}
}