/*
* 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
*/
/*
*/
#include <assert.h>
#include <strings.h>
#include <alloca.h>
#include <stdlib.h>
#include <stdio.h>
#include <dt_parser.h>
#include <dt_impl.h>
#include <dt_provider.h>
#include <dt_module.h>
/*
* This callback function is installed in a given identifier hash to search for
* and apply deferred pragmas that are pending for a given new identifier name.
* Multiple pragmas may be pending for a given name; we processs all of them.
*/
/*ARGSUSED*/
static void
{
return; /* no pragmas pending for current compilation pass */
case DT_IDENT_PRAGAT:
break;
case DT_IDENT_PRAGBN:
break;
}
}
}
/*
* The #pragma attributes directive can be used to reset stability attributes
* on a global identifier or inline definition. If the identifier is already
* defined, we can just change di_attr. If not, we insert the pragma into a
* hash table of the current pcb's deferred pragmas for later processing.
*/
static void
{
"<attributes> <ident>\n", prname);
}
"specified by #pragma %s\n", prname);
}
} else {
"\"%s\" in attribute #pragma "
}
*a = attr;
return;
}
} else if ((idp = dt_idstack_lookup(
"entity defined outside program scope\n", prname);
}
return;
}
}
/*
* The #pragma binding directive can be used to reset the version binding
* on a global identifier or inline definition. If the identifier is already
* defined, we can just change di_vers. If not, we insert the pragma into a
* hash table of the current pcb's deferred pragmas for later processing.
*/
static void
{
const char *name;
"\"version\" <ident>\n", prname);
}
"specified by #pragma %s\n", prname);
}
"entity defined outside program scope\n", prname);
}
return;
}
}
/*
* The #pragma depends_on directive can be used to express a dependency on a
* module, provider or library which if not present will cause processing to
* abort.
*/
static void
{
int found;
"<class> <name>\n", prname);
}
/*
* We have the file we are working on in dtp->dt_filetag
* so find that node and add the dependency in.
*/
dtp->dt_filetag);
lib)) != 0) {
"failed to add dependency %s:%s\n", lib,
}
} else {
/*
* By this point we have already performed a topological
* sort of the dependencies; we process this directive
* as satisfied as long as the dependency was properly
* loaded.
*/
"not explicitly depend on a library");
dtp->dt_filetag);
lib);
if (!dld->dtld_loaded)
"library \"%s\" which failed to load",
lib);
}
} else {
}
if (!found) {
}
}
/*
* The #pragma error directive can be followed by any list of tokens, which we
* just concatenate and print as part of our error message.
*/
static void
{
size_t n = 0;
char *s;
}
s = alloca(n + 1);
s[0] = '\0';
(void) strcat(s, " ");
}
}
}
/*ARGSUSED*/
static void
{
/* ignore any #ident or #pragma ident lines */
}
static void
{
"malformed #pragma %s <option>=<val>\n", prname);
}
"superfluous arguments specified for #pragma %s\n", prname);
}
*val++ = '\0';
"failed to set option '%s': %s\n", opt,
} else {
"failed to set option '%s' to '%s': %s\n",
}
}
}
/*
* The #line directive is used to reset the input line number and to optionally
* note the file name for use in error messages. Sun cpp(1) also produces a
* third integer token after the filename which is one of the following:
*
* 0 - line change has nothing to do with an #include file
* 1 - line change because we just entered a #include file
* 2 - line change because we just exited a #include file
*
* We use these state tokens to adjust pcb_idepth, which in turn controls
* whether type lookups access the global type space or not.
*/
static void
{
"<line> [ [\"file\"] state ]\n", prname);
}
/*
* If a file is specified, free any old pcb_filetag and swap fnp's
* dn_string into pcb_filetag as the new filename for error messages.
*/
/*
* This is not pretty, but is a necessary evil until we either
* write "dpp" or get a useful standalone cpp from DevPro. If
* input file (see dt_preproc() in dt_cc.c), so just clear the
* dt_filetag pointer so error messages refer to the main file.
*/
} else
}
yypcb->pcb_idepth++;
yypcb->pcb_idepth--;
}
}
/*
* D compiler pragma types range from control directives to common pragmas to
* D custom pragmas, in order of specificity. Similar to gcc, we use #pragma D
* as a special prefix for our pragmas so they can be used in mixed headers.
*/
static const struct dt_pragmadesc {
const char *dpd_name;
int dpd_kind;
} dt_pragmas[] = {
};
/*
* Process a control line #directive by looking up the directive name in our
* lookup table and invoking the corresponding function with the token list.
* According to K&R[A12.9], we silently ignore null directive lines.
*/
void
{
break;
}
if (kind == DT_PRAGMA_DIR &&
continue;
}
if (kind == DT_PRAGMA_SUB &&
continue;
}
break;
}
yylineno--; /* since we've already seen \n */
yylineno++;
break;
}
switch (kind) {
case DT_PRAGMA_DIR:
/*NOTREACHED*/
case DT_PRAGMA_SUB:
break; /* K&R[A12.8] says to ignore unknown pragmas */
case DT_PRAGMA_DCP:
default:
}
yylineno++;
break;
}
}