dt_decl.c revision 7266c4fdd3d819c74f84745da19a4eb34bd75f2d
1N/A * The contents of this file are subject to the terms of the 1N/A * Common Development and Distribution License (the "License"). 1N/A * You may not use this file except in compliance with the License. 1N/A * See the License for the specific language governing permissions 1N/A * and limitations under the License. 1N/A * When distributing Covered Code, include this CDDL HEADER in each 1N/A * If applicable, add the following below this CDDL HEADER, with the 1N/A * fields enclosed by brackets "[]" replaced with your own identifying 1N/A * information: Portions Copyright [yyyy] [name of copyright owner] 1N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 1N/A * Copyright (c) 2012, 2014 by Delphix. All rights reserved. 1N/A * Copyright (c) 2013 Joyent, Inc. All rights reserved. 1N/A return (
ddp);
/* nothing to check if the type is not yet set */ 1N/A "long may not be used with char type\n");
1N/A "may not be used with void type\n");
1N/A "unsigned may only be used with integer type\n");
1N/A "long long may only be used with integer or " 1N/A "floating-point type\n");
1N/A "for function or associative array parameter\n");
1N/A "incorrect type specified\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. "be used at most twice in a declaration");
"used at most once in a declaration");
"used at most once in a declaration");
"used at most once in a declaration");
* 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'. * 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. "not use a variable-length argument list\n",
kind);
"use parameter of type %s: %s, parameter #%d\n",
"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");
"expression or tuple signature expected as " "array declaration subscript\n");
* 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. const char *
idname =
ident ?
ident :
"(anon)";
"in a member name (%s)\n",
ident);
"cannot have dynamic member: %s\n",
ident);
* 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. "expression expected as bit-field size\n");
* 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. return (
1);
/* abort search and return true if a member exists */ "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 " * 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);
* 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. * 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. * 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. * 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. * 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>. * 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. * 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. * Allocate space for the type name and enough space for the maximum * additional text ("unsigned long long \0" requires 20 more bytes). * Add dd_name unless a short, long, or long long is explicitly * suffixed by int. We use the C/CTF canonical names for integers. * 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.