int, bool *);
static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *);
+static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *);
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
/* Attributes used by Objective-C. */
{ "NSObject", 0, 0, true, false, false, false,
handle_nsobject_attribute, NULL },
+ { "objc_root_class", 0, 0, true, false, false, false,
+ handle_objc_root_class_attribute, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
return NULL_TREE;
}
+/* Handle a "objc_root_class" attributes; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_objc_root_class_attribute (tree */*node*/, tree name, tree /*args*/,
+ int /*flags*/, bool *no_add_attrs)
+{
+ /* This has no meaning outside Objective-C. */
+ if (!c_dialect_objc())
+ warning (OPT_Wattributes, "%qE is only applicable to Objective-C"
+ " class interfaces, attribute ignored", name);
+
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
/* Attempt to partially validate a single attribute ATTR as if
it were to be applied to an entity OPER. */
extern tree objc_get_class_reference (tree);
extern tree objc_get_class_ivars (tree);
extern bool objc_detect_field_duplicates (bool);
-extern void objc_start_class_interface (tree, tree, tree, tree);
+extern void objc_start_class_interface (tree, location_t, tree, tree, tree);
extern void objc_start_category_interface (tree, tree, tree, tree);
extern void objc_start_protocol (tree, tree, tree);
extern void objc_continue_interface (void);
EnumValue
Enum(cpp_normalize_level) String(nfc) Value(normalized_C)
+Wobjc-root-class
+ObjC ObjC++ Var(warn_objc_root_class) Warning Init(1)
+Warn if a class interface has no superclass. Root classes may use an attribute
+to suppress this warning.
+
Wold-style-cast
C++ ObjC++ Var(warn_old_style_cast) Warning
Warn if a C-style cast is used in a program.
void
objc_start_class_interface (tree ARG_UNUSED (name),
+ location_t /*name_loc*/,
tree ARG_UNUSED (super),
tree ARG_UNUSED (protos),
tree ARG_UNUSED (attribs))
return;
}
id1 = c_parser_peek_token (parser)->value;
+ location_t loc1 = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
tree proto = NULL_TREE;
if (c_parser_next_token_is (parser, CPP_LESS))
proto = c_parser_objc_protocol_refs (parser);
- objc_start_class_interface (id1, superclass, proto, attributes);
+ objc_start_class_interface (id1, loc1, superclass, proto, attributes);
}
else
objc_start_class_implementation (id1, superclass);
bool is_class_extension;
cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */
+ location_t nam_loc = cp_lexer_peek_token (parser->lexer)->location;
name = cp_parser_identifier (parser);
if (name == error_mark_node)
{
objc_start_category_interface (name, categ, protos, attributes);
else
{
- objc_start_class_interface (name, super, protos, attributes);
+ objc_start_class_interface (name, nam_loc, super, protos, attributes);
/* Handle instance variable declarations, if any. */
cp_parser_objc_class_ivars (parser);
objc_continue_interface ();
Otherwise the two shared objects are unable to use the same
typeinfo node and exception handling will break.
+@item objc_root_class @r{(Objective-C and Objective-C++ only)}
+@cindex @code{objc_root_class} type attribute
+This attribute marks a class as being a root class, and thus allows
+the compiler to elide any warnings about a missing superclass and to
+make additional checks for mandatory methods as needed.
+
@end table
To specify multiple attributes, separate them by commas within the
-fzero-link @gol
-gen-decls @gol
-Wassign-intercept -Wno-property-assign-default @gol
--Wno-protocol -Wselector @gol
+-Wno-protocol -Wobjc-root-class -Wselector @gol
-Wstrict-selector-match @gol
-Wundeclared-selector}
methods inherited from the superclass are considered to be implemented,
and no warning is issued for them.
+@item -Wobjc-root-class @r{(Objective-C and Objective-C++ only)}
+@opindex Wobjc-root-class
+Warn if a class interface lacks a superclass. Most classes will inherit
+from @code{NSObject} (or @code{Object}) for example. When declaring
+classes intended to be root classes, the warning can be suppressed by
+marking their interfaces with @code{__attribute__((objc_root_class))}.
+
@item -Wselector @r{(Objective-C and Objective-C++ only)}
@opindex Wselector
@opindex Wno-selector
}
void
-objc_start_class_interface (tree klass, tree super_class,
+objc_start_class_interface (tree klass, location_t name_loc, tree super_class,
tree protos, tree attributes)
{
if (flag_objc1_only && attributes)
- error_at (input_location, "class attributes are not available in Objective-C 1.0");
+ error_at (name_loc, "class attributes are not available in Objective-C 1.0");
objc_interface_context
= objc_ivar_context
CLASS_SUPER_NAME (objc_implementation_context)
= CLASS_SUPER_NAME (implementation_template);
}
+
+ if (!CLASS_SUPER_NAME (objc_implementation_context)
+ && !lookup_attribute ("objc_root_class",
+ TYPE_ATTRIBUTES (implementation_template)))
+ warning (OPT_Wobjc_root_class, "class %qE defined without"
+ " specifying a base class", class_name);
break;
case CLASS_INTERFACE_TYPE:
TREE_DEPRECATED (klass) = 1;
else if (is_attribute_p ("objc_exception", name))
CLASS_HAS_EXCEPTION_ATTR (klass) = 1;
+ else if (is_attribute_p ("objc_root_class", name))
+ ;
else if (is_attribute_p ("visibility", name))
;
else
--- /dev/null
+/* Test Wobjc-root-class warning is suppressed by the objc_root_class attr.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. This should compile without warning. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+__attribute__((objc_root_class))
+@interface ARootObject
+@end
+
+@implementation ARootObject
+@end
--- /dev/null
+/* Test Wobjc-root-class.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+@interface ARootObject
+@end
+
+@implementation ARootObject /* { dg-warning {class 'ARootObject' defined without specifying a base class} } */
+@end
--- /dev/null
+/* Test Wobjc-root-class warning is suppressed by the objc_root_class attr.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. This should compile without warning. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+__attribute__((objc_root_class))
+@interface ARootObject
+@end
+
+@implementation ARootObject
+@end
--- /dev/null
+/* Test Wobjc-root-class.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+@interface ARootObject
+@end
+
+@implementation ARootObject
+@end /* { dg-warning {class 'ARootObject' defined without specifying a base class} } */