widl: Check that attributes are applicable for libraries, modules, dispinterfaces...
authorRob Shearman <rob@codeweavers.com>
Mon, 14 Apr 2008 09:59:46 +0000 (10:59 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 14 Apr 2008 11:39:16 +0000 (13:39 +0200)
tools/widl/parser.y

index c47668b4214711f3bbe4e09b57533ed803604e4a..9824634b59d8400afb01c21a0095094042c8a03a 100644 (file)
@@ -134,6 +134,10 @@ static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t
 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
+static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs);
+static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
+static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs);
+static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs);
 
 #define tsENUM   1
 #define tsSTRUCT 2
@@ -382,7 +386,8 @@ importlib: tIMPORTLIB '(' aSTRING ')'
 
 libraryhdr: tLIBRARY aIDENTIFIER               { $$ = $2; }
        ;
-library_start: attributes libraryhdr '{'       { if (!parse_only) start_typelib($2, $1);
+library_start: attributes libraryhdr '{'       { check_library_attrs($2, $1);
+                                                 if (!parse_only) start_typelib($2, $1);
                                                  if (!parse_only && do_header) write_library($2, $1);
                                                  if (!parse_only && do_idfile) write_libid($2, $1);
                                                }
@@ -737,7 +742,7 @@ coclass:  tCOCLASS aIDENTIFIER                      { $$ = make_class($2); }
        ;
 
 coclasshdr: attributes coclass                 { $$ = $2;
-                                                 $$->attrs = $1;
+                                                 $$->attrs = check_coclass_attrs($2->name, $1);
                                                  if (!parse_only && do_header)
                                                    write_coclass($$);
                                                  if (!parse_only && do_idfile)
@@ -769,7 +774,7 @@ dispinterfacehdr: attributes dispinterface  { attr_t *attrs;
                                                  $$ = $2;
                                                  if ($$->defined) error_loc("multiple definition error\n");
                                                  attrs = make_attr(ATTR_DISPINTERFACE);
-                                                 $$->attrs = append_attr( $1, attrs );
+                                                 $$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
                                                  $$->ref = find_type("IDispatch", 0);
                                                  if (!$$->ref) error_loc("IDispatch is undefined\n");
                                                  $$->defined = TRUE;
@@ -860,7 +865,7 @@ module:   tMODULE aIDENTIFIER                       { $$ = make_type(0, NULL); $$->name = $2; $$->ki
        ;
 
 modulehdr: attributes module                   { $$ = $2;
-                                                 $$->attrs = $1;
+                                                 $$->attrs = check_module_attrs($2->name, $1);
                                                }
        ;
 
@@ -2277,6 +2282,58 @@ static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs)
   return attrs;
 }
 
+static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs)
+{
+  const attr_t *attr;
+  if (!attrs) return attrs;
+  LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
+  {
+    if (!allowed_attr[attr->type].on_library)
+      error_loc("inapplicable attribute %s for library %s\n",
+                allowed_attr[attr->type].display_name, name);
+  }
+  return attrs;
+}
+
+static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
+{
+  const attr_t *attr;
+  if (!attrs) return attrs;
+  LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
+  {
+    if (!allowed_attr[attr->type].on_dispinterface)
+      error_loc("inapplicable attribute %s for dispinterface %s\n",
+                allowed_attr[attr->type].display_name, name);
+  }
+  return attrs;
+}
+
+static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs)
+{
+  const attr_t *attr;
+  if (!attrs) return attrs;
+  LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
+  {
+    if (!allowed_attr[attr->type].on_module)
+      error_loc("inapplicable attribute %s for module %s\n",
+                allowed_attr[attr->type].display_name, name);
+  }
+  return attrs;
+}
+
+static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs)
+{
+  const attr_t *attr;
+  if (!attrs) return attrs;
+  LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
+  {
+    if (!allowed_attr[attr->type].on_coclass)
+      error_loc("inapplicable attribute %s for coclass %s\n",
+                allowed_attr[attr->type].display_name, name);
+  }
+  return attrs;
+}
+
 static void check_all_user_types(ifref_list_t *ifrefs)
 {
   const ifref_t *ifref;