In gcc/: 2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>

In gcc/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * c-parser.c (c_parser_next_token_starts_declspecs): In
        Objective-C, detect Objective-C 2.0 dot-syntax with a class name.
        (c_parser_next_token_starts_declaration): Same.
        (c_parser_postfix_expression): Parse the Objective-C 2.0
        dot-syntax with a class name.

In gcc/cp/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * parser.c (cp_parser_primary_expression): Recognize Objective-C
        2.0 dot-syntax with class names and process it.
        (cp_parser_nonclass_name): Recognize Objective-C 2.0 dot-syntax
        with class names.
        (cp_parser_class_name): Same change.
        (cp_parser_simple_type_specifier): Tidied comments.

In gcc/c-family/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * c-common.h (objc_build_class_component_ref): New.
        * stub-objc.c (objc_build_class_component_ref): New.

In gcc/objc/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * objc-act.c (objc_build_class_component_ref): New.

In gcc/testsuite/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * objc.dg/property/dotsyntax-3.m: New.
        * objc.dg/property/dotsyntax-4.m: New.
        * obj-c++.dg/property/dotsyntax-3.mm: New.
        * obj-c++.dg/property/dotsyntax-4.mm: New.

        * objc.dg/fobjc-std-1.m: Added test for warnings when the
        Objective-C 2.0 dot-syntax is used with class names.
        * obj-c++.dg/fobjc-std-1.mm: Same change.

From-SVN: r166333
This commit is contained in:
Nicola Pero 2010-11-04 20:59:47 +00:00 committed by Nicola Pero
parent 2b78d0f152
commit bede2adc26
16 changed files with 499 additions and 19 deletions

View File

@ -1,3 +1,12 @@
2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
Fixed using the Objective-C 2.0 dot-syntax with class names.
* c-parser.c (c_parser_next_token_starts_declspecs): In
Objective-C, detect Objective-C 2.0 dot-syntax with a class name.
(c_parser_next_token_starts_declaration): Same.
(c_parser_postfix_expression): Parse the Objective-C 2.0
dot-syntax with a class name.
2010-11-04 Pat Haugen <pthaugen@us.ibm.com>
* final.c (compute_alignments): Compute/free loop info all the time.

View File

@ -1,3 +1,9 @@
2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
Fixed using the Objective-C 2.0 dot-syntax with class names.
* c-common.h (objc_build_class_component_ref): New.
* stub-objc.c (objc_build_class_component_ref): New.
2010-11-03 Nicola Pero <nicola.pero@meta-innovation.com>
* c.opt (Wproperty-assign-default): New option.

View File

@ -1037,6 +1037,7 @@ extern bool objc_method_decl (enum tree_code);
extern void objc_add_property_declaration (location_t, tree, bool, bool, bool,
bool, bool, bool, tree, tree);
extern tree objc_maybe_build_component_ref (tree, tree);
extern tree objc_build_class_component_ref (tree, tree);
extern tree objc_maybe_build_modify_expr (tree, tree);
extern void objc_add_synthesize_declaration (location_t, tree);
extern void objc_add_dynamic_declaration (location_t, tree);

View File

@ -349,6 +349,12 @@ objc_maybe_build_component_ref (tree ARG_UNUSED (datum), tree ARG_UNUSED (compon
return 0;
}
tree
objc_build_class_component_ref (tree ARG_UNUSED (datum), tree ARG_UNUSED (component))
{
return 0;
}
tree
objc_maybe_build_modify_expr (tree ARG_UNUSED (lhs), tree ARG_UNUSED (rhs))
{

View File

@ -598,6 +598,19 @@ static inline bool
c_parser_next_token_starts_declspecs (c_parser *parser)
{
c_token *token = c_parser_peek_token (parser);
/* In Objective-C, a classname normally starts a declspecs unless it
is immediately followed by a dot. In that case, it is the
Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
setter/getter on the class. c_token_starts_declspecs() can't
differentiate between the two cases because it only checks the
current token, so we have a special check here. */
if (c_dialect_objc ()
&& token->type == CPP_NAME
&& token->id_kind == C_ID_CLASSNAME
&& c_parser_peek_2nd_token (parser)->type == CPP_DOT)
return false;
return c_token_starts_declspecs (token);
}
@ -607,6 +620,14 @@ static inline bool
c_parser_next_token_starts_declaration (c_parser *parser)
{
c_token *token = c_parser_peek_token (parser);
/* Same as above. */
if (c_dialect_objc ()
&& token->type == CPP_NAME
&& token->id_kind == C_ID_CLASSNAME
&& c_parser_peek_2nd_token (parser)->type == CPP_DOT)
return false;
return c_token_starts_declaration (token);
}
@ -5821,6 +5842,7 @@ c_parser_alignof_expression (c_parser *parser)
@protocol ( identifier )
@encode ( type-name )
objc-string-literal
Classname . identifier
*/
static struct c_expr
@ -5867,20 +5889,48 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
break;
case CPP_NAME:
if (c_parser_peek_token (parser)->id_kind != C_ID_ID)
switch (c_parser_peek_token (parser)->id_kind)
{
case C_ID_ID:
{
tree id = c_parser_peek_token (parser)->value;
c_parser_consume_token (parser);
expr.value = build_external_ref (loc, id,
(c_parser_peek_token (parser)->type
== CPP_OPEN_PAREN),
&expr.original_type);
break;
}
case C_ID_CLASSNAME:
{
/* Here we parse the Objective-C 2.0 Class.name dot
syntax. */
tree class_name = c_parser_peek_token (parser)->value;
tree component;
c_parser_consume_token (parser);
gcc_assert (c_dialect_objc ());
if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
{
expr.value = error_mark_node;
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
expr.value = error_mark_node;
break;
}
component = c_parser_peek_token (parser)->value;
c_parser_consume_token (parser);
expr.value = objc_build_class_component_ref (class_name,
component);
break;
}
default:
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
break;
}
{
tree id = c_parser_peek_token (parser)->value;
c_parser_consume_token (parser);
expr.value = build_external_ref (loc, id,
(c_parser_peek_token (parser)->type
== CPP_OPEN_PAREN),
&expr.original_type);
}
break;
case CPP_OPEN_PAREN:
/* A parenthesized expression, statement expression or compound

View File

@ -1,3 +1,13 @@
2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
Fixed using the Objective-C 2.0 dot-syntax with class names.
* parser.c (cp_parser_primary_expression): Recognize Objective-C
2.0 dot-syntax with class names and process it.
(cp_parser_nonclass_name): Recognize Objective-C 2.0 dot-syntax
with class names.
(cp_parser_class_name): Same change.
(cp_parser_simple_type_specifier): Tidied comments.
2010-11-04 Jason Merrill <jason@redhat.com>
PR c++/46298

View File

@ -3908,6 +3908,22 @@ cp_parser_primary_expression (cp_parser *parser,
if (ambiguous_decls)
return error_mark_node;
/* In Objective-C++, we may have an Objective-C 2.0
dot-syntax for classes here. */
if (c_dialect_objc ()
&& cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
&& TREE_CODE (decl) == TYPE_DECL
&& objc_is_class_name (decl))
{
tree component;
cp_lexer_consume_token (parser->lexer);
component = cp_parser_identifier (parser);
if (component == error_mark_node)
return error_mark_node;
return objc_build_class_component_ref (id_expression, component);
}
/* In Objective-C++, an instance variable (ivar) may be preferred
to whatever cp_parser_lookup_name() found. */
decl = objc_lookup_ivar (decl, id_expression);
@ -12786,14 +12802,14 @@ cp_parser_simple_type_specifier (cp_parser* parser,
return error_mark_node;
}
/* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user thought
that the type was a template. */
if (type && type != error_mark_node)
{
/* As a last-ditch effort, see if TYPE is an Objective-C type.
If it is, then the '<'...'>' enclose protocol names rather than
template arguments, and so everything is fine. */
/* See if TYPE is an Objective-C type, and if so, parse and
accept any protocol references following it. Do this before
the cp_parser_check_for_invalid_template_id() call, because
Objective-C types can be followed by '<...>' which would
enclose protocol names rather than template arguments, and so
everything is fine. */
if (c_dialect_objc () && !parser->scope
&& (objc_is_id (type) || objc_is_class_name (type)))
{
@ -12808,6 +12824,9 @@ cp_parser_simple_type_specifier (cp_parser* parser,
return qual_type;
}
/* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user
thought that the type was a template. */
cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
token->location);
}
@ -12888,9 +12907,17 @@ cp_parser_nonclass_name (cp_parser* parser)
if (type)
type_decl = TYPE_NAME (type);
}
/* Issue an error if we did not find a type-name. */
if (TREE_CODE (type_decl) != TYPE_DECL)
if (TREE_CODE (type_decl) != TYPE_DECL
/* In Objective-C, we have the complication that class names are
normally type names and start declarations (eg, the
"NSObject" in "NSObject *object;"), but can be used in an
Objective-C 2.0 dot-syntax (as in "NSObject.version") which
is an expression. So, a classname followed by a dot is not a
valid type-name. */
|| (objc_is_class_name (TREE_TYPE (type_decl))
&& cp_lexer_peek_token (parser->lexer)->type == CPP_DOT))
{
if (!cp_parser_simulate_error (parser))
cp_parser_name_lookup_error (parser, identifier, type_decl,
@ -16714,7 +16741,12 @@ cp_parser_class_name (cp_parser *parser,
}
else if (TREE_CODE (decl) != TYPE_DECL
|| TREE_TYPE (decl) == error_mark_node
|| !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)))
|| !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))
/* In Objective-C 2.0, a classname followed by '.' starts a
dot-syntax expression, and it's not a type-name. */
|| (c_dialect_objc ()
&& cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
&& objc_is_class_name (decl)))
decl = error_mark_node;
if (decl == error_mark_node)

View File

@ -1,3 +1,8 @@
2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
Fixed using the Objective-C 2.0 dot-syntax with class names.
* objc-act.c (objc_build_class_component_ref): New.
2010-11-03 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_add_dynamic_declaration): Allow @dynamic in a

View File

@ -1301,6 +1301,79 @@ objc_maybe_build_component_ref (tree object, tree property_ident)
return NULL_TREE;
}
/* This hook routine is invoked by the parser when an expression such
as 'xxx.yyy' is parsed, and 'xxx' is a class name. This is the
Objective-C 2.0 dot-syntax applied to classes, so we need to
convert it into a setter/getter call on the class. */
tree
objc_build_class_component_ref (tree class_name, tree property_ident)
{
tree x = NULL_TREE;
tree object, rtype;
if (flag_objc1_only)
error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
if (class_name == NULL_TREE || class_name == error_mark_node
|| TREE_CODE (class_name) != IDENTIFIER_NODE)
return error_mark_node;
if (property_ident == NULL_TREE || property_ident == error_mark_node
|| TREE_CODE (property_ident) != IDENTIFIER_NODE)
return NULL_TREE;
object = objc_get_class_reference (class_name);
if (!object)
{
/* We know that 'class_name' is an Objective-C class name as the
parser won't call this function if it is not. This is only a
double-check for safety. */
error_at (input_location, "could not find class %qE", class_name);
return error_mark_node;
}
rtype = lookup_interface (class_name);
if (!rtype)
{
/* Again, this should never happen, but we do check. */
error_at (input_location, "could not find interface for class %qE", class_name);
return error_mark_node;
}
x = maybe_make_artificial_property_decl (rtype, NULL_TREE,
property_ident,
true);
if (x)
{
tree expression;
if (TREE_DEPRECATED (x))
warn_deprecated_use (x, NULL_TREE);
expression = build2 (PROPERTY_REF, TREE_TYPE(x), object, x);
SET_EXPR_LOCATION (expression, input_location);
TREE_SIDE_EFFECTS (expression) = 1;
/* See above for why we do this. */
if (!PROPERTY_HAS_NO_GETTER (x))
objc_finish_message_expr (object,
PROPERTY_GETTER_NAME (x),
NULL_TREE);
return expression;
}
else
{
error_at (input_location, "could not find setter/getter for %qE in class %qE",
property_ident, class_name);
return error_mark_node;
}
return NULL_TREE;
}
/* This is used because we don't want to expose PROPERTY_REF to the
C/C++ frontends. Maybe we should! */
bool

View File

@ -1,3 +1,15 @@
2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
Fixed using the Objective-C 2.0 dot-syntax with class names.
* objc.dg/property/dotsyntax-3.m: New.
* objc.dg/property/dotsyntax-4.m: New.
* obj-c++.dg/property/dotsyntax-3.mm: New.
* obj-c++.dg/property/dotsyntax-4.mm: New.
* objc.dg/fobjc-std-1.m: Added test for warnings when the
Objective-C 2.0 dot-syntax is used with class names.
* obj-c++.dg/fobjc-std-1.mm: Same change.
2010-11-04 Pat Haugen <pthaugen@us.ibm.com>
* gcc.target/powerpc/loop_align.c: New.

View File

@ -13,6 +13,7 @@ __attribute__ ((deprecated))
int b;
}
+ (id) alloc __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */
+ (id) name;
- (id) init;
- (id) testMe: (id) __attribute__((unused)) argument; /* { dg-error "not available in Objective.C 1.0" } */
@property (nonatomic) int a; /* { dg-error "not available in Objective.C 1.0" } */
@ -21,6 +22,7 @@ __attribute__ ((deprecated))
@implementation MyRootClass
+ (id) alloc { return self; }
+ (id) name { return self; }
- (id) init { return self; }
- (id) testMe: (id) __attribute__((unused)) argument { return self; } /* { dg-error "not available in Objective.C 1.0" } */
@synthesize a; /* { dg-error "not available in Objective.C 1.0" } */
@ -52,4 +54,9 @@ int array_length (NSArray *array)
return i;
}
#endif
#endif
id test (void)
{
return MyRootClass.name; /* { dg-error "not available in Objective.C 1.0" } */
}

View File

@ -0,0 +1,63 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do run } */
/* Test the 'dot syntax' without a declarated property. This tests the case where
the object is a Class. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
static int a;
static id b;
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
+ (int) count;
+ (void) setCount: (int)value;
+ (id) next;
+ (void) setNext: (id)value;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
+ (int) count
{
return a;
}
+ (void) setCount: (int)value
{
a = value;
}
+ (id) next
{
return b;
}
+ (void) setNext: (id)value
{
b = value;
}
@end
int main (void)
{
MyRootClass *object = [[MyRootClass alloc] init];
MyRootClass.count = 40;
if (MyRootClass.count != 40)
abort ();
MyRootClass.next = object;
if (MyRootClass.next != object)
abort ();
return 0;
}

View File

@ -0,0 +1,69 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test the 'dot syntax' without a declarated property. This tests
syntax errors in the case where the object is a Class. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
static int a;
static id b;
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
+ (int) count;
+ (void) setCount: (int)value;
+ (id) next;
+ (void) setNext: (id)value;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
+ (int) count
{
return a;
}
+ (void) setCount: (int)value
{
a = value;
}
+ (id) next
{
return b;
}
+ (void) setNext: (id)value
{
b = value;
}
@end
int main (void)
{
MyRootClass *object = [[MyRootClass alloc] init];
MyRootClass.invalid = 40; /* { dg-error "could not find setter.getter" } */
if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */
abort ();
MyRootClass.; /* { dg-error "expected identifier" } */
if (MyRootClass.) /* { dg-error "expected identifier" } */
abort ();
MyRootClass.int; /* { dg-error "expected identifier" } */
/* { dg-error "expected" "" { target *-*-* } 62 } */
if (MyRootClass.int) /* { dg-error "expected identifier" } */
/* { dg-error "expected" "" { target *-*-* } 64 } */
abort ();
return 0;
}

View File

@ -13,6 +13,7 @@ __attribute__ ((deprecated))
int b;
}
+ (id) alloc __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */
+ (id) name;
- (id) init;
- (id) testMe: (id) __attribute__((unused)) argument; /* { dg-error "not available in Objective.C 1.0" } */
@property (nonatomic) int a; /* { dg-error "not available in Objective.C 1.0" } */
@ -21,6 +22,7 @@ __attribute__ ((deprecated))
@implementation MyRootClass
+ (id) alloc { return self; }
+ (id) name { return self; }
- (id) init { return self; }
- (id) testMe: (id) __attribute__((unused)) argument { return self; } /* { dg-error "not available in Objective.C 1.0" } */
@synthesize a; /* { dg-error "not available in Objective.C 1.0" } */
@ -52,3 +54,8 @@ int array_length (NSArray *array)
return i;
}
id test (void)
{
return MyRootClass.name; /* { dg-error "not available in Objective.C 1.0" } */
}

View File

@ -0,0 +1,63 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do run } */
/* Test the 'dot syntax' without a declarated property. This tests the case where
the object is a Class. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
static int a;
static id b;
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
+ (int) count;
+ (void) setCount: (int)value;
+ (id) next;
+ (void) setNext: (id)value;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
+ (int) count
{
return a;
}
+ (void) setCount: (int)value
{
a = value;
}
+ (id) next
{
return b;
}
+ (void) setNext: (id)value
{
b = value;
}
@end
int main (void)
{
MyRootClass *object = [[MyRootClass alloc] init];
MyRootClass.count = 40;
if (MyRootClass.count != 40)
abort ();
MyRootClass.next = object;
if (MyRootClass.next != object)
abort ();
return 0;
}

View File

@ -0,0 +1,67 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test the 'dot syntax' without a declarated property. This tests
syntax errors in the case where the object is a Class. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
static int a;
static id b;
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
+ (int) count;
+ (void) setCount: (int)value;
+ (id) next;
+ (void) setNext: (id)value;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
+ (int) count
{
return a;
}
+ (void) setCount: (int)value
{
a = value;
}
+ (id) next
{
return b;
}
+ (void) setNext: (id)value
{
b = value;
}
@end
int main (void)
{
MyRootClass *object = [[MyRootClass alloc] init];
MyRootClass.invalid = 40; /* { dg-error "could not find setter.getter" } */
if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */
abort ();
MyRootClass.; /* { dg-error "expected identifier" } */
if (MyRootClass.) /* { dg-error "expected identifier" } */
abort ();
MyRootClass.int; /* { dg-error "expected identifier" } */
if (MyRootClass.int) /* { dg-error "expected identifier" } */
abort ();
return 0;
}