2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * DTrace D Language Parser 2N/A * The D Parser is a lex/yacc parser consisting of the lexer dt_lex.l, the 2N/A * parsing grammar dt_grammar.y, and this file, dt_parser.c, which handles 2N/A * the construction of the parse tree nodes and their syntactic validation. 2N/A * The parse tree is constructed of dt_node_t structures (see <dt_parser.h>) 2N/A * that are built in two passes: (1) the "create" pass, where the parse tree 2N/A * nodes are allocated by calls from the grammar to dt_node_*() subroutines, 2N/A * and (2) the "cook" pass, where nodes are coalesced, assigned D types, and 2N/A * validated according to the syntactic rules of the language. 2N/A * All node allocations are performed using dt_node_alloc(). All node frees 2N/A * during the parsing phase are performed by dt_node_free(), which frees node- 2N/A * internal state but does not actually free the nodes. All final node frees 2N/A * are done as part of the end of dt_compile() or as part of destroying 2N/A * persistent identifiers or translators which have embedded nodes. 2N/A * The dt_node_* routines that implement pass (1) may allocate new nodes. The 2N/A * dt_cook_* routines that implement pass (2) may *not* allocate new nodes. 2N/A * They may free existing nodes using dt_node_free(), but they may not actually 2N/A * deallocate any dt_node_t's. Currently dt_cook_op2() is an exception to this 2N/A * rule: see the comments therein for how this issue is resolved. 2N/A * The dt_cook_* routines are responsible for (at minimum) setting the final 2N/A * are set manually (i.e. not by one of the type assignment functions), then 2N/A * the DT_NF_COOKED flag must be set manually on the node. 2N/A * The cooking pass can be applied to the same parse tree more than once (used 2N/A * in the case of a comma-separated list of probe descriptions). As such, the 2N/A * cook routines must not perform any parse tree transformations which would 2N/A * be invalid if the tree were subsequently cooked using a different context. 2N/A * The dn_ctfp and dn_type fields form the type of the node. This tuple can 2N/A * take on the following set of values, which form our type invariants: 2N/A * 1. dn_ctfp = NULL, dn_type = CTF_ERR 2N/A * In this state, the node has unknown type and is not yet cooked. The 2N/A * DT_NF_COOKED flag is not yet set on the node. 2N/A * 2. dn_ctfp = DT_DYN_CTFP(dtp), dn_type = DT_DYN_TYPE(dtp) 2N/A * In this state, the node is a dynamic D type. This means that generic 2N/A * operations are not valid on this node and only code that knows how to 2N/A * examine the inner details of the node can operate on it. A <DYN> node 2N/A * must have dn_ident set to point to an identifier describing the object 2N/A * and its type. The DT_NF_REF flag is set for all nodes of type <DYN>. 2N/A * At present, the D compiler uses the <DYN> type for: 2N/A * - associative arrays that do not yet have a value type defined 2N/A * - translated data (i.e. the result of the xlate operator) 2N/A * 3. dn_ctfp = DT_STR_CTFP(dtp), dn_type = DT_STR_TYPE(dtp) 2N/A * In this state, the node is of type D string. The string type is really 2N/A * a char[0] typedef, but requires special handling throughout the compiler. 2N/A * 4. dn_ctfp != NULL, dn_type = any other type ID 2N/A * In this state, the node is of some known D/CTF type. The normal libctf 2N/A * APIs can be used to learn more about the type name or structure. When 2N/A * the type is assigned, the DT_NF_SIGNED, DT_NF_REF, and DT_NF_BITFIELD 2N/A * flags cache the corresponding attributes of the underlying CTF type. 2N/A default:
return (
"<?>");
2N/A p++;
/* skip leading whitespace prior to token */ 2N/A break;
/* empty string or single token remaining */ 2N/A * Copy from the start of the token (p) to the location 2N/A * backquote (q) to extract the nul-terminated object. 2N/A * Copy the original string up to the start of this 2N/A * token (p) into type, and then concatenate everything 2N/A * after q. This is the type name without the object. 2N/A * When we parse type expressions or parse an expression with unary "&", we 2N/A * need to find a type that is a pointer to a previously known type. 2N/A * Unfortunately CTF is limited to a per-container view, so ctf_type_pointer() 2N/A * alone does not suffice for our needs. We provide a more intelligent wrapper 2N/A * for the compiler that attempts to compute a pointer to either the given type 2N/A * or its base (that is, we try both "foo_t *" and "struct foo *"), and also 2N/A * to potentially construct the required type on-the-fly. 2N/A * Perform the "usual arithmetic conversions" to determine which of the two 2N/A * input operand types should be promoted and used as a result type. The 2N/A * rules for this are described in ISOC[6.3.1.8] and K&R[A6.5]. 2N/A * Compute an integer rank based on the size and unsigned status. 2N/A * If rank is identical, pick the "larger" of the equivalent types 2N/A * which we define as having a larger base ctf_id_t. If rank is 2N/A * different, pick the type with the greater rank. 2N/A "probe description %s:%s:%s:%s",
2N/A * dt_node_xalloc() can be used to create new parse nodes from any libdtrace 2N/A * caller. The caller is responsible for assigning dn_link appropriately. 2N/A * dt_node_alloc() is used to create new parse nodes from the parser. It 2N/A * assigns the node location based on the current lexer line number and places 2N/A * the new node on the default allocation list. If allocation fails, we 2N/A * automatically longjmp the caller back to the enclosing compilation call. 2N/A * Determine if the specified parse tree node references an identifier of the 2N/A * specified kind, and if so return a pointer to it; otherwise return NULL. 2N/A * This function resolves the identifier itself, following through any inlines. 2N/A * The size of the node as used for the sizeof() operator depends on 2N/A * the kind of the node. If the node is a SYM, the size is obtained 2N/A * from the symbol table; if it is not a SYM, the size is determined 2N/A * from the node's type. This is slightly different from C's sizeof() 2N/A * operator in that (for example) when applied to a function, sizeof() 2N/A * will evaluate to the length of the function rather than the size of 2N/A * the function type. 2N/A return (0);
/* void integer */ 2N/A return (0);
/* void cannot be used as a scalar */ 2N/A return (0);
/* type is not a pointer */ 2N/A return (
1);
/* promote char pointer to string */ 2N/A return (
1);
/* promote char array to string */ 2N/A return (0);
/* string are pass-by-ref but act like structs */ 2N/A return (0);
/* <DYN> is an alias for void but not the same */ 2N/A return (0);
/* fail if either node is a dynamic variable */ 2N/A return (0);
/* fail if both nodes are integers */ 2N/A return (0);
/* fail if lp is an integer that isn't 0 constant */ 2N/A return (0);
/* fail if rp is an integer that isn't 0 constant */ 2N/A return (0);
/* fail if only one pointer is a userland address */ 2N/A * Resolve the left-hand and right-hand types to their base type, and 2N/A * then resolve the referenced type as well (assuming the base type 2N/A * is CTF_K_POINTER or CTF_K_ARRAY). Otherwise [lr]ref = CTF_ERR. 2N/A * We know that one or the other type may still be a zero-valued 2N/A * integer constant. To simplify the code below, set the integer 2N/A * type variables equal to the non-integer types and proceed. 2N/A * The types are compatible if both are pointers to the same type, or 2N/A * if either pointer is a void pointer. If they are compatible, set 2N/A * tp to point to the more specific pointer type and return it. 2N/A * The rules for checking argument types against parameter types are described 2N/A * in the ANSI-C spec (see K&R[A7.3.2] and K&R[A7.17]). We use the same rule 2N/A * set to determine whether associative array arguments match the prototype. 2N/A return (
1);
/* integer types are compatible */ 2N/A return (
1);
/* string types are compatible */ 2N/A return (
1);
/* stack types are compatible */ 2N/A return (
1);
/* symaddr types are compatible */ 2N/A return (
1);
/* usymaddr types are compatible */ 2N/A * We provide dt_node_is_posconst() as a convenience routine for callers who 2N/A * wish to verify that an argument is a positive non-zero integer constant. 2N/A * The original rules for integer constant typing are described in K&R[A2.5.1]. 2N/A * However, since we support long long, we instead use the rules from ISO C99 2N/A * clause 6.4.4.1 since that is where long longs are formally described. The 2N/A * rules require us to know whether the constant was specified in decimal or 2N/A * in octal or hex, which we do by looking at our lexer's 'yyintdecimal' flag. 2N/A * The type of an integer constant is the first of the corresponding list in 2N/A * which its value can be represented: 2N/A * unsuffixed decimal: int, long, long long 2N/A * unsuffixed oct/hex: int, unsigned int, long, unsigned long, 2N/A * long long, unsigned long long 2N/A * suffix [uU]: unsigned int, unsigned long, unsigned long long 2N/A * suffix [lL] decimal: long, long long 2N/A * suffix [lL] oct/hex: long, unsigned long, long long, unsigned long long 2N/A * suffix [uU][Ll]: unsigned long, unsigned long long 2N/A * suffix [uU][ll/LL]: unsigned long long 2N/A * Given that our lexer has already validated the suffixes by regexp matching, 2N/A * there is an obvious way to concisely encode these rules: construct an array 2N/A * of the types in the order int, unsigned int, long, unsigned long, long long, 2N/A * unsigned long long. Compute an integer array starting index based on the 2N/A * suffix (e.g. none = 0, u = 1, ull = 5), and compute an increment based on 2N/A * the specifier (dec/oct/hex) and suffix (u). Then iterate from the starting 2N/A * index to the end, advancing using the increment, and searching until we 2N/A * find a limit that matches or we run out of choices (overflow). To make it 2N/A * even faster, we precompute the table of type information in dtrace_open(). 2N/A if (c ==
'U' || c ==
'u')
2N/A else if (c ==
'L' || c ==
'l')
2N/A * If a prefix character is present in macro text, add 2N/A * in the corresponding operator node (see dt_lex.l). 2N/A return (
NULL);
/* keep gcc happy */ 2N/A * If the identifier is an inlined integer constant, then create an INT 2N/A * node that is a clone of the inline parse tree node and return that 2N/A * immediately, allowing this inline to be used in parsing contexts 2N/A * that require constant expressions (e.g. scalar array sizes). 2N/A * Create an empty node of type corresponding to the given declaration. 2N/A * Explicit references to user types (C or D) are assigned the default 2N/A * stability; references to other types are _dtrace_typattr (Private). 2N/A * If 'ddp' is NULL, we get a decl by popping the decl stack. This 2N/A * form of dt_node_type() is used by parameter rules in dt_grammar.y. 2N/A * Create a type node corresponding to a varargs (...) parameter by just 2N/A * assigning it type CTF_ERR. The decl processing code will handle this. 2N/A * Instantiate a decl using the contents of the current declaration stack. As 2N/A * we do not currently permit decls to be initialized, this function currently 2N/A * returns NULL and no parse node is created. When this function is called, 2N/A * the topmost scope's ds_ident pointer will be set to NULL (indicating no 2N/A * init_declarator rule was matched) or will point to the identifier to use. 2N/A * If we have no declaration identifier, then this is either a spurious 2N/A * declaration of an intrinsic type (e.g. "extern int;") or declaration 2N/A * or redeclaration of a struct, union, or enum type or tag. 2N/A * If we are nested inside of a C include file, add the declaration to 2N/A * the C definition module; otherwise use the D definition module. 2N/A * If we see a global or static declaration of a function prototype, 2N/A * treat this as equivalent to a D extern declaration. 2N/A "appropriate in D\n");
2N/A "\t current: %s\n\tprevious: %s\n",
2N/A * If the source type for the typedef is not defined in the 2N/A * target container or its parent, copy the type to the target 2N/A * container and reset dtt_ctfp and dtt_type to the copy. 2N/A "array declaration requires array dimension or " 2N/A * Cache some attributes of the decl to make the rest of this 2N/A * code simpler: if the decl is an array which is subscripted 2N/A * by a type rather than an integer, then it's an associative 2N/A * array (assc). We then expect to match either DT_IDENT_ARRAY 2N/A * for associative arrays or DT_IDENT_SCALAR for anything else. 2N/A * Create a fake dt_node_t on the stack so we can determine the 2N/A * type of any matching identifier by assigning to this node. 2N/A * If the pre-existing ident has its di_type set, propagate 2N/A * the type by hand so as not to trigger a prototype check for 2N/A * arrays (yet); otherwise we use dt_ident_cook() on the ident 2N/A * to ensure it is fully initialized before looking at it. 2N/A "may not be declared as local variables:" 2N/A "\t current: %s %s\n\tprevious: %s %s\n",
2N/A continue;
/* tuple length mismatch */ 2N/A "identifier redeclared: %s\n" 2N/A "\t current: %s, key #%d of type %s\n" 2N/A "\tprevious: %s, key #%d of type %s\n",
2N/A "identifier redeclared: %s\n" 2N/A "\t current: %s of %s, tuple length %d\n" 2N/A "\tprevious: %s of %s, tuple length %d\n",
2N/A break;
/* proceed to declaring */ 2N/A "on number of %s variables exceeded\n",
2N/A * If we are declaring an associative array, use our 2N/A * fake parse node to cook the new assoc identifier. 2N/A * This will force the ident code to instantiate the 2N/A * array type signature corresponding to the list of 2N/A * types pointed to by ddp->dd_node. We also reset 2N/A * the identifier's attributes based upon the result. 2N/A }
/* end of switch */ 2N/A "function designator is not of function type\n");
2N/A * The offsetof() function is special because it takes a type name as an 2N/A * argument. It does not actually construct its own node; after looking up the 2N/A * structure or union offset, we just return an integer node with the offset. 2N/A "offsetof operand must be a struct or union type\n");
2N/A "cannot take offset of a bit-field: %s\n",
name);
2N/A * If we're negating an unsigned integer, zero out any 2N/A * extra top bits to truncate the value to the size of 2N/A * the effective type determined by dt_node_int(). 2N/A * If sizeof is applied to a type_name or string constant, we can 2N/A * transform 'cp' into an integer constant in the node construction 2N/A * pass so that it can then be used for arithmetic in this pass. 2N/A "operand of unknown size\n");
2N/A * First we check for operations that are illegal -- namely those that 2N/A * might result in integer division by zero, and abort if one is found. 2N/A * If both children are immediate values, we can just perform inline 2N/A * calculation and return a new immediate node with the result. 2N/A * If an integer constant is being cast to another integer type, we can 2N/A * perform the cast as part of integer constant folding in this pass. 2N/A * We must take action when the integer is being cast to a smaller type 2N/A * or if it is changing signed-ness. If so, we first shift rp's bits 2N/A * bits high (losing excess bits if narrowing) and then shift them down 2N/A * with either a logical shift (unsigned) or arithmetic shift (signed). 2N/A * If no immediate optimizations are available, create an new OP2 node 2N/A * and glue the left and right children into place and return. 2N/A "providers",
"modules",
"functions" 2N/A "appropriate for inline declaration\n");
2N/A "inline definition\n\tprevious: %s %s\n",
2N/A * If we are declaring an inlined array, verify that we have a tuple 2N/A * signature, and then recompute 'dtt' as the array's value type. 2N/A * If the inline identifier is not defined, then create it with the 2N/A * orphan flag set. We do not insert the identifier into dt_globals 2N/A * until we have successfully cooked the right-hand expression, below. 2N/A * If we're inlining an associative array, create a private identifier 2N/A * hash containing the named parameters and store it in inp->din_hash. 2N/A * We then push this hash on to the top of the pcb_globals stack. 2N/A i++;
/* count up parameters for din_argv[] */ 2N/A * Create an identifier for each parameter as a scalar inline, 2N/A * and store it in din_hash and in position in din_argv[]. The 2N/A * parameter identifiers also use dt_idops_inline, but we leave 2N/A * the dt_idnode_t argument 'pinp' zeroed. This will be filled 2N/A * in by the code generation pass with references to the args. 2N/A continue;
/* ignore anonymous parameters */ 2N/A * Unlike most constructors, we need to explicitly cook the right-hand 2N/A * side of the inline definition immediately to prevent recursion. If 2N/A * the right-hand side uses the inline itself, the cook will fail. 2N/A * Set the type, attributes, and flags for the inline. If the right- 2N/A * hand expression has an identifier, propagate its flags. Then cook 2N/A * the identifier to fully initialize it: if we're declaring an inline 2N/A * associative array this will construct a type signature from 'ddp'. 2N/A * Store the parse tree nodes for 'expr' inside of idp->di_data ('inp') 2N/A * so that they will be preserved with this identifier. Then pop the 2N/A * inline declaration from the declaration stack and restore the lexer. 2N/A * Finally, insert the inline identifier into dt_globals to make it 2N/A * visible, and then cook 'dnp' to check its type against 'expr'. 2N/A "translator from %s to %s has already been declared\n",
2N/A "translator output type must be a struct or union\n");
2N/A "contain scoping operator: %s\n",
name);
2N/A "contain scoping operator: %s\n",
name);
2N/A * Check to see if the provider is already defined or visible through 2N/A * dtrace(7D). If so, set dn_provred to treat it as a re-declaration. 2N/A * If not, create a new provider and set its interface-only flag. This 2N/A * flag may be cleared later by calls made to dt_probe_declare(). 2N/A * Store all parse nodes created since we consumed the DT_KEY_PROVIDER 2N/A * token with the provider and then restore our lexing state to CLAUSE. 2N/A * Note that if dnp->dn_provred is true, we may end up storing dups of 2N/A * a provider's interface and implementation: we eat this space because 2N/A * the implementation will likely need to redeclare probe members, and 2N/A * therefore may result in those member nodes becoming persistent. 2N/A continue;
/* skip to end of allocation list */ 2N/A * This function provides the underlying implementation of cooking an 2N/A * identifier given its node, a hash of dynamic identifiers, an identifier 2N/A * kind, and a boolean flag indicating whether we are allowed to instantiate 2N/A * a new identifier if the string is not found. This function is either 2N/A * called from dt_cook_ident(), below, or directly by the various cooking 2N/A * routines that are allowed to instantiate identifiers (e.g. op2 TOK_ASGN). 2N/A * Look for scoping marks in the identifier. If one is found, set our 2N/A * scope to either DTRACE_OBJ_KMODS or UMODS or to the first part of 2N/A * the string that specifies the scope using an explicit module name. 2N/A * If two marks in a row are found, set 'uref' (user symbol reference). 2N/A * Otherwise we set scope to DTRACE_OBJ_EXEC, indicating that normal 2N/A * scope is desired and we should search the specified idhash. 2N/A *
name++ =
'\0';
/* leave name pointing after scoping mark */ 2N/A * If create is set to false, and we fail our idhash lookup, preset 2N/A * the errno code to EDT_NOVAR for our final error message below. 2N/A * If we end up calling dtrace_lookup_by_name(), it will reset the 2N/A * errno appropriately and that error will be reported instead. 2N/A * Check that we are referencing the ident in the manner that 2N/A * matches its type if this is a global lookup. In the TLS or 2N/A * local case, we don't know how the ident will be used until 2N/A * the time operator -> is seen; more parsing is needed. 2N/A * Arrays and aggregations are not cooked individually. They 2N/A * have dynamic types and must be referenced using operator []. 2N/A * This is handled explicitly by the code for DT_TOK_LBRAC. 2N/A static const char *
const kunames[] = {
"kernel",
"user" };
2N/A * For now, we special-case EDT_DATAMODEL to clarify 2N/A * that mixed data models are not currently supported. 2N/A "%s%s%s in a %s D program\n",
2N/A "no symbolic type information is available for " 2N/A * Arrays and aggregations are not cooked individually. They 2N/A * have dynamic types and must be referenced using operator []. 2N/A * This is handled explicitly by the code for DT_TOK_LBRAC. 2N/A * Since operators [ and -> can instantiate new variables before we know 2N/A * whether the reference is for a read or a write, we need to check read 2N/A * references to determine if the identifier is currently dt_ident_unref(). 2N/A * If so, we report that this first access was to an undefined variable. 2N/A "%s%s has not yet been declared or assigned\n",
2N/A * We allow the unary ++ and -- operators to instantiate new scalar 2N/A * variables if applied to an identifier; otherwise just cook as usual. 2N/A * If the deref operator is applied to a translated pointer, 2N/A * we can just set our output type to the base translation. 2N/A "cannot dereference non-pointer type\n");
2N/A "cannot dereference pointer to void\n");
2N/A "cannot dereference pointer to function\n");
2N/A * If we propagated the l-value bit and the child operand was 2N/A * a writable D variable or a binary operation of the form 2N/A * a + b where a is writable, then propagate the writable bit. 2N/A * This is necessary to permit assignments to scalar arrays, 2N/A * which are converted to expressions of the form *(a + i). 2N/A "cannot take address of dynamic variable\n");
2N/A "cannot take address of dynamic object\n");
2N/A "unacceptable operand for unary & operator\n");
2N/A "cannot take address of bit-field\n");
2N/A "cannot apply sizeof to a bit-field\n");
2N/A "operand of unknown size\n");
2N/A "cannot apply stringof to a value of type %s\n",
2N/A * The expression E1[E2] is identical by definition to *((E1)+(E2)) so 2N/A * we convert "[" to "+" and glue on "*" at the end (see K&R[A7.3.1]) 2N/A * unless the left-hand side is an untyped D scalar, associative array, 2N/A * or aggregation. In these cases, we proceed to case DT_TOK_LBRAC and 2N/A * handle associative array and aggregation references there. 2N/A * Switch op to '+' for *(E1 + E2) array mode in these cases: 2N/A * (a) lp is a DT_IDENT_ARRAY variable that has already been 2N/A * referenced using [] notation (dn_args != NULL). 2N/A * (b) lp is a non-ARRAY variable that has already been given 2N/A * a type by assignment or declaration (!dt_ident_unref()) 2N/A * (c) lp is neither a variable nor an aggregation 2N/A * The D comparison operators provide the ability to transform 2N/A * a right-hand identifier into a corresponding enum tag value 2N/A * if the left-hand side is an enum type. To do this, we cook 2N/A * the left-hand side, and then see if the right-hand side is 2N/A * an unscoped identifier defined in the enum. If so, we 2N/A * convert into an integer constant node with the tag's value. 2N/A "ambiguous use of operator %s: %s is " 2N/A "both a %s enum tag and a global %s\n",
2N/A * The rules for type checking for the relational operators are 2N/A * described in the ANSI-C spec (see K&R[A7.9-10]). We perform 2N/A * the various tests in order from least to most expensive. We 2N/A * also allow derived strings to be compared as a first-class 2N/A * type (resulting in a strcmp(3C)-style comparison), and we 2N/A * slightly relax the A7.9 rules to permit void pointer 2N/A * comparisons as in A7.10. Our users won't be confused by 2N/A * this since they understand pointers are just numbers, and 2N/A * relaxing this constraint simplifies the implementation. 2N/A "incompatible types: \"%s\" %s \"%s\"\n",
2N/A * The rules for type checking for the additive operators are 2N/A * described in the ANSI-C spec (see K&R[A7.7]). Pointers and 2N/A * integers may be manipulated according to specific rules. In 2N/A * these cases D permits strings to be treated as pointers. 2N/A "types: \"%s\" %s \"%s\"\n",
2N/A * If the left-hand side is an identifier, attempt to resolve 2N/A * it as either an aggregation or scalar variable. We pass 2N/A * B_TRUE to dt_xcook_ident to indicate that a new variable can 2N/A * be created if no matching variable exists in the namespace. 2N/A * If the left-hand side is an aggregation, verify that we are 2N/A * assigning it the result of an aggregating function. Once 2N/A * we've done so, hide the func node in the aggregation and 2N/A * return the aggregation itself up to the parse tree parent. 2N/A * This transformation is legal since the assigned function 2N/A * cannot change identity across disjoint cooking passes and 2N/A * the argument list subtree is retained for later cooking. 2N/A "@%s must be assigned the result of " 2N/A "aggregation redefined: @%s\n\t " 2N/A "current: @%s = %s( )\n\tprevious: @%s = " 2N/A * Do not allow multiple aggregation assignments in a 2N/A * single statement, e.g. (@a = count()) = count(); 2N/A * We produce a message as if the result of aggregating 2N/A * function does not propagate DT_NF_LVALUE. 2N/A "modifiable lvalue as an operand\n");
2N/A * If the right-hand side is a dynamic variable that is the 2N/A * output of a translator, our result is the translated type. 2N/A * If the left-hand side of an assignment statement is a virgin 2N/A * variable created by this compilation pass, reset the type of 2N/A * this variable to the type of the right-hand side. 2N/A * The rules for type checking for the assignment operators are 2N/A * described in the ANSI-C spec (see K&R[A7.17]). We share 2N/A * most of this code with the argument list checking code. 2N/A "applied to operand of type \"%s\"\n",
2N/A "operands have incompatible types: \"%s\" %s \"%s\"\n",
2N/A "incompatible types: \"%s\" %s \"%s\"\n",
2N/A * The rules for type checking for the assignment operators are 2N/A * described in the ANSI-C spec (see K&R[A7.17]). To these 2N/A * rules we add that only writable D nodes can be modified. 2N/A "operator %s requires left-hand scalar " 2N/A "incompatible types: \"%s\" %s \"%s\"\n",
2N/A /* see K&R[A7.17] */ 2N/A * If the left-hand side of operator -> is the name "self", 2N/A * then we permit a TLS variable to be created or referenced. 2N/A * If the left-hand side of operator -> is the name "this", 2N/A * then we permit a local variable to be created or referenced. 2N/A * If the left-hand side is a translated struct or ptr, 2N/A * the type of the left is the translation output type. 2N/A "translator does not define conversion " 2N/A * If we follow a reference to a forward declaration tag, 2N/A * search the entire type space for the actual definition. 2N/A "operator %s cannot be applied to a " 2N/A "forward declaration: no %s definition " 2N/A "applied to pointer to type \"%s\"; must " 2N/A "be applied to a struct or union pointer\n",
2N/A "applied to type \"%s\"; must be applied " 2N/A * If op is DT_TOK_LBRAC, we know from the special-case code at 2N/A * the top that lp is either a D variable or an aggregation. 2N/A * If the left-hand side is an aggregation, just set dn_aggtup 2N/A * to the right-hand side and return the cooked aggregation. 2N/A * This transformation is legal since we are just collapsing 2N/A * nodes to simplify later processing, and the entire aggtup 2N/A * parse subtree is retained for subsequent cooking passes. 2N/A "reference @%s as a multi-dimensional " 2N/A * If the left-hand side is a non-global scalar that hasn't yet 2N/A * been referenced or modified, it was just created by self-> 2N/A * or this-> and we can convert it from scalar to assoc array. 2N/A "local variables may not be used as " 2N/A * Now that we've confirmed our left-hand side is a DT_NODE_VAR 2N/A * of idkind DT_IDENT_ARRAY, we need to splice the [ node from 2N/A * the parse tree and leave a cooked DT_NODE_VAR in its place 2N/A * where dn_args for the VAR node is the right-hand 'rp' tree, 2N/A * as shown in the parse tree diagram below: 2N/A * [ OP2 "[" ]=dnp [ VAR ]=dnp 2N/A * / \ +- dn_args -> [ ??? ]=rp 2N/A * [ VAR ]=lp [ ??? ]=rp 2N/A * Since the final dt_node_cook(dnp) can fail using longjmp we 2N/A * must perform the transformations as a group first by over- 2N/A * writing 'dnp' to become the VAR node, so that the parse tree 2N/A * is guaranteed to be in a consistent state if the cook fails. 2N/A "cannot translate from \"%s\" to \"%s\"\n",
2N/A * The rules for casting are loosely explained in K&R[A7.5] 2N/A * and K&R[A6]. Basically, we can cast to the same type or 2N/A * same base type, between any kind of scalar values, from 2N/A * arrays to pointers, and we can cast anything to void. 2N/A * To these rules D adds casts from scalars to strings. 2N/A "invalid cast expression: \"%s\" to \"%s\"\n",
2N/A * Complete the conversion of E1[E2] to *((E1)+(E2)) that we started 2N/A * at the top of our switch() above (see K&R[A7.3.1]). Since E2 is 2N/A * parsed as an argument_expression_list by dt_grammar.y, we can 2N/A * end up with a comma-separated list inside of a non-associative 2N/A * array reference. We check for this and report an appropriate error. 2N/A "cannot access %s as an associative array\n",
2N/A * Cook callbacks are not typically permitted to allocate nodes. 2N/A * When we do, we must insert them in the middle of an existing 2N/A * allocation list rather than having them appended to the pcb 2N/A * list because the sub-expression may be part of a definition. 2N/A "operator ?: expression must be of scalar type\n");
2N/A "operator ?: operands cannot be of dynamic type\n");
2N/A * The rules for type checking for the ternary operator are complex and 2N/A * are described in the ANSI-C spec (see K&R[A7.16]). We implement 2N/A * the various tests in order from least to most expensive. 2N/A "operator ?: operands must have compatible types\n");
2N/A "used in a conditional context\n");
2N/A * If dn_aggfun is set, this node is a collapsed aggregation assignment (see 2N/A * the special case code for DT_TOK_ASGN in dt_cook_op2() above), in which 2N/A * case we cook both the tuple and the function call. If dn_aggfun is NULL, 2N/A * this node is just a reference to the aggregation's type and attributes. 2N/A * Since D permits new variable identifiers to be instantiated in any program 2N/A * expression, we may need to cook a clause's predicate either before or after 2N/A * the action list depending on the program code in question. Consider: 2N/A * probe-description-list probe-description-list 2N/A * trace(x); trace(x++); 2N/A * In the left-hand example, the predicate uses operator ++ to instantiate 'x' 2N/A * as a variable of type int64_t. The predicate must be cooked first because 2N/A * otherwise the statement trace(x) refers to an unknown identifier. In the 2N/A * right-hand example, the action list uses ++ to instantiate 'x'; the action 2N/A * list must be cooked first because otherwise the predicate x == 0 refers to 2N/A * an unknown identifier. In order to simplify programming, we support both. 2N/A * When cooking a clause, we cook the action statements before the predicate by 2N/A * default, since it seems more common to create or modify identifiers in the 2N/A * action list. If cooking fails due to an unknown identifier, we attempt to 2N/A * cook the predicate (i.e. do it first) and then go back and cook the actions. 2N/A * If this, too, fails (or if we get an error other than D_IDENT_UNDEF) we give 2N/A * up and report failure back to the user. There are five possible paths: 2N/A * cook actions = OK, cook predicate = OK -> OK 2N/A * cook actions = OK, cook predicate = ERR -> ERR 2N/A * cook actions = ERR, cook predicate = ERR -> ERR 2N/A * cook actions = ERR, cook predicate = OK, cook actions = OK -> OK 2N/A * cook actions = ERR, cook predicate = OK, cook actions = ERR -> ERR 2N/A * The programmer can still defeat our scheme by creating circular definition 2N/A * dependencies between predicates and actions, as in this example clause: 2N/A * probe-description-list 2N/A * but it doesn't seem worth the complexity to handle such rare cases. The 2N/A * user can simply use the D variable declaration syntax to work around them. 2N/A * Before assigning dn_ctxattr, temporarily assign the probe attribute 2N/A * to 'dnp' itself to force an attribute check and minimum violation. 2N/A "predicate result must be of scalar type\n");
2N/A * If we are inlining a translation, verify that the inline declaration 2N/A * type exactly matches the type that is returned by the translation. 2N/A * Otherwise just use dt_node_is_argcompat() to check the types. 2N/A "inline %s definition uses incompatible types: " 2N/A "inline %s definition uses incompatible types: " 2N/A * Before cooking each translator member, we push a reference to the 2N/A * hash containing translator-local identifiers on to pcb_globals to 2N/A * temporarily interpose these identifiers in front of other globals. 2N/A "translator member %s is not a member of %s\n",
2N/A "translator member %s definition uses " 2N/A "incompatible types: \"%s\" = \"%s\"\n",
2N/A "probe %s:%s %s prototype mismatch:\n" 2N/A "\t current: %u arg%s\n\tprevious: %u arg%s\n",
2N/A "probe %s:%s %s prototype argument #%u mismatch:\n" 2N/A "\t current: %s\n\tprevious: %s\n",
2N/A * Compare a new probe declaration with an existing probe definition (either 2N/A * from a previous declaration or cached from the kernel). If the existing 2N/A * definition and declaration both have an input and output parameter list, 2N/A * compare both lists. Otherwise compare only the output parameter lists. 2N/A "provider interface mismatch: %s\n" 2N/A "\t current: probe %s:%s has an output prototype\n" 2N/A "\tprevious: probe %s:%s has no output prototype\n",
2N/A continue;
/* no translator defined and none required */ 2N/A "argument #%u from %s to %s is not defined\n",
2N/A * If we're declaring a provider for the first time and it is unknown 2N/A * to dtrace(7D), insert the probe definitions into the provider's hash. 2N/A * If we're redeclaring a known provider, verify the interface matches. 2N/A "provider interface mismatch: %s\n" 2N/A "\t current: probe %s:%s defined\n" 2N/A "\tprevious: probe %s:%s not defined\n",
2N/A * The dt_ident_t for any clause-local identifier is freed once we leave the 2N/A * scope of that identifier. If we use a clause-local in an inline, e.g.: 2N/A * inline char io_type = (this->io->io_type == ZIO_TYPE_NULL) ? '.' : '?'; 2N/A * the dt_node_t for the inline will have a dangling reference to the 2N/A * dt_ident_t. We fix this by making a copy of the dt_ident_t in the 2N/A * Recursively cook the parse tree starting at the specified node. The idflags 2N/A * parameter is used to indicate the type of reference (r/w) and is applied to 2N/A * the resulting identifier if it is a D variable or D aggregation. 2N/A * Compute the DOF dtrace_diftype_t representation of a node's type. This is 2N/A * called from a variety of places in the library so it cannot assume yypcb 2N/A * is valid: any references to handle-specific data must be made through 'dtp'. 2N/A return;
/* compiler is not currently active: act as a no-op */ 2N/A return;
/* compiler is not currently active: act as a no-op */ 2N/A *p =
'\0';
/* crop at newline */ 2N/A return (
1);
/* indicate that lex should return a zero token for EOF */