зеркало из https://github.com/mozilla/gecko-dev.git
Various fixes to xpidl. Note that this checkin will cause a rebuild of everything that depends on nsISupports.h. Fixes courtesy Mike Shaver, with small tweaks by McCabe. r=shaver, r=mccabe.
- Fix to bug 17013; have xpidl produce an error when encountering a native declaration without an associated (c++-name). - remove many DEBUG_shaver lines. - provide xpidl_tree_warning as a fallback for libIDL versions for which IDL_tree warning is bad, and NULL-proof our message callback function. Also remove a 1k buffer limit from the message callback function. - make enum in IDL files an error. We don't support it, and love consts instead. - Fix to 12684; don't allow [retval] parameter + return or multiple [retval] parameters. - Fix to 13390; make non-{short,long} const a fatal error.
This commit is contained in:
Родитель
e60a23b7ac
Коммит
578b8c54a1
|
@ -43,17 +43,18 @@
|
|||
* ## idiom, which allows us to pass through varargs calls.
|
||||
*/
|
||||
#if !(LIBIDL_MAJOR_VERSION == 0 && LIBIDL_MINOR_VERSION == 6 && \
|
||||
LIBIDL_MICRO_VERSION == 5)
|
||||
LIBIDL_MICRO_VERSION == 5) && !defined(DEBUG_shaver)
|
||||
/*
|
||||
* This turns a varargs call to XPIDL_WARNING directly into a varargs call to
|
||||
* IDL_tree_warning. The only tricky bit is that you must call XPIDL_WARNING
|
||||
* with extra parens, e.g. XPIDL_WARNING((foo, bar, "sil"))
|
||||
* This turns a varargs call to XPIDL_WARNING directly into a varargs
|
||||
* call to IDL_tree_warning or xpidl_tree_warning as appropriate. The
|
||||
* only tricky bit is that you must call XPIDL_WARNING with extra
|
||||
* parens, e.g. XPIDL_WARNING((foo, bar, "sil"))
|
||||
*
|
||||
* Probably best removed when we leave 6.5.
|
||||
*/
|
||||
* Probably best removed when we leave 6.5. */
|
||||
#define XPIDL_WARNING(x) IDL_tree_warning##x
|
||||
#else
|
||||
#define XPIDL_WARNING(x) do { } while (0)
|
||||
extern void xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...);
|
||||
#define XPIDL_WARNING(x) xpidl_tree_warning##x
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -196,4 +197,11 @@ xpidl_parse_iid(nsID *id, const char *str);
|
|||
gboolean
|
||||
verify_method_declaration(IDL_tree method_tree);
|
||||
|
||||
/*
|
||||
* Verify that a native declaration has an associated C++ expression, i.e. that
|
||||
* it's of the form native <idl-name>(<c++-name>)
|
||||
*/
|
||||
gboolean
|
||||
check_native(TreeState *state);
|
||||
|
||||
#endif /* __xpidl_h */
|
||||
|
|
|
@ -487,26 +487,9 @@ attr_dcl(TreeState *state)
|
|||
static gboolean
|
||||
do_enum(TreeState *state)
|
||||
{
|
||||
XPIDL_WARNING((state->tree, IDL_WARNING1,
|
||||
"enums not supported, enum \'%s\' ignored",
|
||||
IDL_IDENT(IDL_TYPE_ENUM(state->tree).ident).str));
|
||||
return TRUE;
|
||||
#if 0
|
||||
IDL_tree enumb = state->tree, iter;
|
||||
|
||||
fprintf(state->file, "enum %s {\n",
|
||||
IDL_IDENT(IDL_TYPE_ENUM(enumb).ident).str);
|
||||
|
||||
for (iter = IDL_TYPE_ENUM(enumb).enumerator_list;
|
||||
iter;
|
||||
iter = IDL_LIST(iter).next) {
|
||||
fprintf(state->file, " %s%s\n", IDL_IDENT(IDL_LIST(iter).data).str,
|
||||
IDL_LIST(iter).next ? ",": "");
|
||||
}
|
||||
|
||||
fputs("};\n\n", state->file);
|
||||
return TRUE;
|
||||
#endif
|
||||
IDL_tree_error(state->tree, "enums not supported, "
|
||||
"see http://bugzilla.mozilla.org/show_bug.cgi?id=8781");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -542,8 +525,9 @@ do_const_dcl(TreeState *state)
|
|||
name, (int) IDL_INTEGER(dcl->const_exp).value);
|
||||
} else {
|
||||
IDL_tree_error(state->tree,
|
||||
"const decl \'%s\' must be of type short or long",
|
||||
"const declaration \'%s\' must be of type short or long",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -769,10 +753,11 @@ static gboolean
|
|||
codefrag(TreeState *state)
|
||||
{
|
||||
const char *desc = IDL_CODEFRAG(state->tree).desc;
|
||||
if (strcmp(desc, "C++")) {
|
||||
|
||||
if (strcmp(desc, "C++") && /* libIDL bug? */ strcmp(desc, "C++\r")) {
|
||||
XPIDL_WARNING((state->tree, IDL_WARNING1,
|
||||
"ignoring '%%{%s' escape. "
|
||||
"(Use '%%{C++' to escape verbatim code.)", desc));
|
||||
"(Use '%%{C++' to escape verbatim C++ code.)", desc));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -785,8 +770,9 @@ nodeHandler *
|
|||
xpidl_header_dispatch(void)
|
||||
{
|
||||
static nodeHandler table[IDLN_LAST];
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!table[IDLN_NONE]) {
|
||||
if (!initialized) {
|
||||
table[IDLN_NONE] = pass_1;
|
||||
table[IDLN_LIST] = list;
|
||||
table[IDLN_ATTR_DCL] = attr_dcl;
|
||||
|
@ -797,6 +783,8 @@ xpidl_header_dispatch(void)
|
|||
table[IDLN_CODEFRAG] = codefrag;
|
||||
table[IDLN_TYPE_DCL] = do_typedef;
|
||||
table[IDLN_CONST_DCL] = do_const_dcl;
|
||||
table[IDLN_NATIVE] = check_native;
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return table;
|
||||
|
|
|
@ -104,14 +104,19 @@ static int
|
|||
msg_callback(int level, int num, int line, const char *file,
|
||||
const char *message)
|
||||
{
|
||||
char *warning_message;
|
||||
|
||||
if (!file)
|
||||
file = "<unknown file>";
|
||||
warning_message = g_strdup_printf("%s:%d: %s\n", file, line, message);
|
||||
|
||||
#ifdef XP_MAC
|
||||
static char warning_message[1024];
|
||||
sprintf(warning_message, "%s:%d: %s\n", file, line, message);
|
||||
mac_warning(warning_message);
|
||||
#else
|
||||
/* XXX Mac */
|
||||
fprintf(stderr, "%s:%d: %s\n", file, line, message);
|
||||
fputs(warning_message, stderr);
|
||||
#endif
|
||||
|
||||
free(warning_message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -888,3 +893,50 @@ verify_method_declaration(IDL_tree method_tree)
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that a native declaration has an associated C++ expression, i.e. that
|
||||
* it's of the form native <idl-name>(<c++-name>)
|
||||
*/
|
||||
gboolean
|
||||
check_native(TreeState *state)
|
||||
{
|
||||
char *native_name;
|
||||
/* require that native declarations give a native type */
|
||||
if (IDL_NATIVE(state->tree).user_type)
|
||||
return TRUE;
|
||||
native_name = IDL_IDENT(IDL_NATIVE(state->tree).ident).str;
|
||||
IDL_tree_error(state->tree,
|
||||
"``native %s;'' needs C++ type: ``native %s(<C++ type>);''",
|
||||
native_name, native_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our own version of IDL_tree_warning, which we use when IDL_tree_warning
|
||||
* would crash on us.
|
||||
*/
|
||||
void
|
||||
xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *msg, *file;
|
||||
int lineno;
|
||||
|
||||
/* XXX need to check against __IDL_max_msg_level, no accessor */
|
||||
va_start(ap, fmt);
|
||||
msg = g_strdup_vprintf(fmt, ap);
|
||||
|
||||
if (p) {
|
||||
file = p->_file;
|
||||
lineno = p->_line;
|
||||
} else {
|
||||
file = NULL;
|
||||
lineno = 0;
|
||||
}
|
||||
|
||||
/* call our message callback, like IDL_tree_warning would */
|
||||
msg_callback(level, 0 /* unused in callee */, lineno, file, msg);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
|
|
@ -463,12 +463,7 @@ pass_1(TreeState *state)
|
|||
destroy_header:
|
||||
/* XXX XPT_DestroyHeader(HEADER(state)) */
|
||||
|
||||
#ifdef DEBUG_shaver
|
||||
fprintf(stderr, "writing typelib was %ssuccessful\n",
|
||||
ok ? "" : "not ");
|
||||
#else
|
||||
; /* msvc would like a statement here */
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
@ -853,18 +848,10 @@ handle_iid_is:
|
|||
}
|
||||
}
|
||||
if (isID) {
|
||||
#ifdef DEBUG_shaver
|
||||
fprintf(stderr, "doing nsID for %s\n",
|
||||
IDL_IDENT(type).str);
|
||||
#endif
|
||||
td->prefix.flags = TD_PNSIID | XPT_TDP_POINTER;
|
||||
if(IDL_tree_property_get(type, "ref"))
|
||||
td->prefix.flags |= XPT_TDP_REFERENCE;
|
||||
} else {
|
||||
#ifdef DEBUG_shaver
|
||||
fprintf(stderr, "not doing nsID for %s\n",
|
||||
IDL_IDENT(type).str);
|
||||
#endif
|
||||
td->prefix.flags = TD_VOID | XPT_TDP_POINTER;
|
||||
}
|
||||
break;
|
||||
|
@ -894,11 +881,12 @@ handle_iid_is:
|
|||
}
|
||||
IDL_tree_error(type, "can't handle %s ident in param list\n",
|
||||
#ifdef DEBUG_shaver
|
||||
IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))
|
||||
/* XXX is this safe to use on Win now? */
|
||||
IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))
|
||||
#else
|
||||
"that type of"
|
||||
"that type of"
|
||||
#endif
|
||||
);
|
||||
);
|
||||
#ifdef DEBUG_shaver
|
||||
XPT_ASSERT(0);
|
||||
#endif
|
||||
|
@ -908,7 +896,8 @@ handle_iid_is:
|
|||
default:
|
||||
IDL_tree_error(type, "can't handle %s in param list\n",
|
||||
#ifdef DEBUG_shaver
|
||||
IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))
|
||||
/* XXX is this safe to use on Win now? */
|
||||
IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))
|
||||
#else
|
||||
"that type"
|
||||
#endif
|
||||
|
@ -1035,6 +1024,7 @@ typelib_op_dcl(TreeState *state)
|
|||
IDL_tree iter;
|
||||
uint16 num_args = 0;
|
||||
uint8 op_flags = 0;
|
||||
gboolean saw_retval = FALSE;
|
||||
gboolean op_notxpcom = (IDL_tree_property_get(op->ident, "notxpcom")
|
||||
!= NULL);
|
||||
gboolean op_noscript = (IDL_tree_property_get(op->ident, "noscript")
|
||||
|
@ -1070,9 +1060,22 @@ typelib_op_dcl(TreeState *state)
|
|||
|
||||
for (num_args = 0, iter = op->parameter_dcls; iter;
|
||||
iter = IDL_LIST(iter).next, num_args++) {
|
||||
if (!fill_pd_from_param(state, &meth->params[num_args],
|
||||
IDL_LIST(iter).data))
|
||||
XPTParamDescriptor *pd = &meth->params[num_args];
|
||||
if (!fill_pd_from_param(state, pd, IDL_LIST(iter).data))
|
||||
return FALSE;
|
||||
if (pd->flags & XPT_PD_RETVAL) {
|
||||
if (op->op_type_spec) {
|
||||
IDL_tree_error(state->tree,
|
||||
"can't have [retval] with non-void return type");
|
||||
return FALSE;
|
||||
}
|
||||
if (saw_retval) {
|
||||
IDL_tree_error(state->tree,
|
||||
"can't have more than one [retval] parameter");
|
||||
return FALSE;
|
||||
}
|
||||
saw_retval = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX unless [notxpcom] */
|
||||
|
@ -1286,6 +1289,7 @@ xpidl_typelib_dispatch(void)
|
|||
table[IDLN_INTERFACE] = typelib_interface;
|
||||
table[IDLN_CONST_DCL] = typelib_const_dcl;
|
||||
table[IDLN_TYPE_ENUM] = typelib_enum;
|
||||
table[IDLN_NATIVE] = check_native;
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче