This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / gmcs / cs-parser.jay
index bf3e8357b8f0e278a5f35357f169677fb0785fa4..112788986c9d52bac6f08d7b0e8de11dfebd1320 100755 (executable)
@@ -1,5 +1,4 @@
-
-        %{
+%{
 //
 // cs-parser.jay: The Parser for the C# compiler
 //
@@ -26,65 +25,85 @@ using System;
 namespace Mono.CSharp
 {
        using System.Collections;
-       using Mono.Languages;
 
        /// <summary>
        ///    The C# Parser
        /// </summary>
-       public class CSharpParser : GenericParser {
+       public class CSharpParser {
                NamespaceEntry  current_namespace;
                TypeContainer   current_container;
        
                IIteratorContainer iterator_container;
 
-               // <summary>
-               //   Current block is used to add statements as we find
-               //   them.  
-               // </summary>
+               /// <summary>
+               ///   Current block is used to add statements as we find
+               ///   them.  
+               /// </summary>
 
                Block      current_block;
 
-               // <summary>
-               //   Current interface is used by the various declaration
-               //   productions in the interface declaration to "add"
-               //   the interfaces as we find them.
-               // </summary>
+               /// <summary>
+                ///   If true, creates a toplevel block in the block production
+                ///   This is flagged by the delegate creation
+                /// </summary>
+                bool       create_toplevel_block;
+
+                /// <summary>
+               /// <summary>
+               ///   Current interface is used by the various declaration
+               ///   productions in the interface declaration to "add"
+               ///   the interfaces as we find them.
+               /// </summary>
                Interface  current_interface;
 
-               // <summary>
-               //   This is used by the unary_expression code to resolve
-               //   a name against a parameter.  
-               // </summary>
+               Delegate   current_delegate;
+
+               /// <summary>
+               ///   This is used by the unary_expression code to resolve
+               ///   a name against a parameter.  
+               /// </summary>
                Parameters current_local_parameters;
 
-               // <summary>
-               //   Using during property parsing to describe the implicit
-               //   value parameter that is passed to the "set" and "get"accesor
-               //   methods (properties and indexers).
-               // </summary>
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" and "get"accesor
+               ///   methods (properties and indexers).
+               /// </summary>
                Expression implicit_value_parameter_type;
                Parameters indexer_parameters;
 
-               // <summary>
-               //   Used to determine if we are parsing the get/set pair
-               //   of an indexer or a property
-               // </summmary>
+               /// <summary>
+               ///   Used to determine if we are parsing the get/set pair
+               ///   of an indexer or a property
+               /// </summmary>
                bool  parsing_indexer;
 
-               //
-               // An out-of-band stack.
-               //
+               ///
+               /// An out-of-band stack.
+               ///
                Stack oob_stack;
 
-               //
-               // Switch stack.
-               //
+               ///
+               /// Switch stack.
+               ///
                Stack switch_stack;
 
-               //
-               // The current file.
-               //
+               public bool yacc_verbose_flag;
+
+               // Name of the file we are parsing
+               public string name;
+
+               ///
+               /// The current file.
+               ///
                SourceFile file;
+               
+               
+               /// Current attribute target
+               string current_attr_target;
+               
+               /// assembly and module attribute definition is enabled
+               bool global_attrs_enabled = true;
 %}
 
 %token EOF
@@ -95,6 +114,7 @@ namespace Mono.CSharp
 /*
  *These are the C# keywords
  */
+%token FIRST_KEYWORD
 %token ABSTRACT        
 %token AS
 %token ADD
@@ -174,15 +194,16 @@ namespace Mono.CSharp
 %token VIRTUAL 
 %token VOID    
 %token VOLATILE
+%token WHERE
 %token WHILE   
-
-/* v2 tokens */
-%token YIELD
+%token ARGLIST
 
 /* C# keywords which are not really keywords */
 %token GET           "get"
 %token SET           "set"
 
+%left LAST_KEYWORD
+
 /* C# single character operators/punctuation. */
 %token OPEN_BRACE    "{"
 %token CLOSE_BRACE   "}"
@@ -201,7 +222,9 @@ namespace Mono.CSharp
 %token BANG           "!"
 %token ASSIGN         "="
 %token OP_LT          "<"
+%token OP_GENERICS_LT "<"
 %token OP_GT          ">"
+%token OP_GENERICS_GT ">"
 %token BITWISE_AND    "&"
 %token BITWISE_OR     "|"
 %token STAR           "*"
@@ -242,6 +265,11 @@ namespace Mono.CSharp
 %token LITERAL_STRING            "string literal"
 
 %token IDENTIFIER
+%token CLOSE_PARENS_CAST
+%token CLOSE_PARENS_NO_CAST
+%token CLOSE_PARENS_OPEN_PARENS
+%token CLOSE_PARENS_MINUS
+%token DEFAULT_OPEN_PARENS
 
 /* Add precedence rules to solve dangling else s/r conflict */
 %nonassoc LOWPREC
@@ -267,8 +295,8 @@ namespace Mono.CSharp
 
 compilation_unit
         : outer_declarations opt_EOF
-        | outer_declarations attribute_sections opt_EOF
-        | attribute_sections opt_EOF
+        | outer_declarations global_attributes opt_EOF
+        | global_attributes opt_EOF
        | opt_EOF /* allow empty files */
         ;
        
@@ -301,7 +329,10 @@ using_alias_directive
        : USING IDENTIFIER ASSIGN 
          namespace_or_type_name SEMICOLON
          {
-                 current_namespace.UsingAlias ((string) $2, (string) $4, lexer.Location);
+               current_namespace.UsingAlias ((string) $2, (MemberName) $4, lexer.Location);
+         }
+       | USING error {
+               CheckIdentifierToken (yyToken);
          }
        ;
 
@@ -318,21 +349,14 @@ using_namespace_directive
 // detach them
 // 
 namespace_declaration
-       : opt_attributes NAMESPACE qualified_identifier 
+       : opt_attributes NAMESPACE namespace_name
        {
-               Attributes attrs = (Attributes) $1;
-
-               if (attrs != null) {
-                       foreach (AttributeSection asec in attrs.AttributeSections)
-                               if (asec.Target == "assembly")
-                                       RootContext.AddGlobalAttributeSection (current_container, asec);
-                               else
-                                       Report.Error(1518, Lexer.Location,
-                                       "Attributes cannot be applied to namespaces."
+               if ($1 != null) {
+                       Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
                                        + " Expected class, delegate, enum, interface, or struct");
                }
 
-               current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3);
+               current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3, lexer.Location);
        } 
          namespace_body opt_semicolon
          { 
@@ -350,15 +374,15 @@ opt_comma
        | COMMA
        ;
 
-qualified_identifier
-       : IDENTIFIER
-       | qualified_identifier DOT IDENTIFIER { 
-           $$ = (($1).ToString ()) + "." + ($3.ToString ()); }
-       ;
+namespace_name
+       : namespace_or_type_name {
+               MemberName name = (MemberName) $1;
 
+               if (name.TypeArguments != null)
+                       syntax_error (lexer.Location, "namespace name expected");
 
-namespace_name
-       : namespace_or_type_name
+               $$ = name.GetName ();
+         }
        ;
 
 namespace_body
@@ -413,6 +437,13 @@ namespace_member_declaration
        | namespace_declaration {
                current_namespace.DeclarationFound = true;
          }
+
+       | field_declaration {
+               Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
+         }
+       | method_declaration {
+               Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
+         }
        ;
 
 type_declaration
@@ -425,6 +456,7 @@ type_declaration
 // Enable this when we have handled all errors, because this acts as a generic fallback
 //
 //     | error {
+//             Console.WriteLine ("Token=" + yyToken);
 //             Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate");
 //       }
        ;
@@ -433,58 +465,93 @@ type_declaration
 // Attributes 17.2
 //
 
+global_attributes
+       : attribute_sections
+{
+       if ($1 != null)
+               CodeGen.Assembly.AddAttributes (((Attributes)$1).Attrs);
+
+       $$ = $1;
+}
+
 opt_attributes
         : /* empty */
-       | attribute_sections { $$ = $1; }
+         {
+               global_attrs_enabled = false;
+               $$ = null;
+      }
+       | attribute_sections
+         { 
+               global_attrs_enabled = false;
+               $$ = $1;
+         }
         ;
  
+
 attribute_sections
        : attribute_section
           {
-               AttributeSection sect = (AttributeSection) $1;
-
-               if (sect.Target == "assembly") 
-                       RootContext.AddGlobalAttributeSection (current_container, sect);
-               
+               ArrayList sect = (ArrayList) $1;
 
-               $$ = new Attributes ((AttributeSection) $1);
+               if (global_attrs_enabled) {
+                       if (current_attr_target == "module") {
+                               CodeGen.Module.AddAttributes (sect);
+                       $$ = null;
+                       } else if (current_attr_target == "assembly") {
+                               CodeGen.Assembly.AddAttributes (sect);
+                       $$ = null;
+                       } else {
+                               $$ = new Attributes (sect);
+               }
+               } else {
+                       $$ = new Attributes (sect);
           }
+               current_attr_target = null;
+      }
        | attribute_sections attribute_section
          {
-               Attributes attrs = null;
-               AttributeSection sect = (AttributeSection) $2;
+               Attributes attrs = $1 as Attributes;
+               ArrayList sect = (ArrayList) $2;
 
-               if (sect.Target == "assembly")
-                       RootContext.AddGlobalAttributeSection (current_container, sect);
-
-               if ($1 != null) {
-                       attrs = (Attributes) $1;
-                       attrs.AddAttributeSection (sect);
+               if (global_attrs_enabled) {
+                       if (current_attr_target == "module") {
+                               CodeGen.Module.AddAttributes (sect);
+                               $$ = null;
+                       } else if (current_attr_target == "assembly") {
+                               CodeGen.Assembly.AddAttributes (sect);
+                               $$ = null;
+                       } else {
+                               if (attrs == null)
+                                       attrs = new Attributes (sect);
+                               else
+                                       attrs.AddAttributes (sect);                     
+               }
+               } else {
+                       if (attrs == null)
+                               attrs = new Attributes (sect);
+                       else
+                               attrs.AddAttributes (sect);
                }
-               
                $$ = attrs;
+               current_attr_target = null;
          }
        ;
 
 attribute_section
        : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
          {
-               string target = null;
-               
-               if ($2 != null)
-                       target = (string) $2;
-               
-               $$ = new AttributeSection (target, (ArrayList) $3);
+               $$ = $3;
          }
         | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
          {
-               $$ = new AttributeSection (null, (ArrayList) $2);
+               $$ = $2;
          }
        ;
  
 attribute_target_specifier
        : attribute_target COLON
          {
+               current_attr_target = (string)$1;
                $$ = $1;
          }
        ;
@@ -524,12 +591,24 @@ attribute
          }
          opt_attribute_arguments
          {
-               $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+               MemberName mname = (MemberName) $1;
+               if (mname.IsGeneric) {
+                       Report.Error (404, lexer.Location,
+                                     "'<' unexpected: attributes cannot be generic");
+               }
+
+               string name = mname.GetName ();
+               if (current_attr_target == "assembly" || current_attr_target == "module")
+                       $$ = new GlobalAttribute (current_container, current_attr_target,
+                                                 name, (ArrayList) $3, (Location) $2);
+               else
+                       $$ = new Attribute (current_attr_target, name, (ArrayList) $3,
+                                           (Location) $2);
          }
        ;
 
 attribute_name
-       : type_name  { /* reserved attribute name or identifier: 17.4 */ }
+       : namespace_or_type_name  { /* reserved attribute name or identifier: 17.4 */ }
        ;
 
 opt_attribute_arguments
@@ -652,23 +731,29 @@ class_member_declaration
 struct_declaration
        : opt_attributes
          opt_modifiers
-         STRUCT IDENTIFIER
+         STRUCT member_name
          { 
                Struct new_struct;
-               string full_struct_name = MakeName ((string) $4);
+               MemberName full_struct_name = MakeName ((MemberName) $4);
 
-               new_struct = new Struct (current_container, full_struct_name, (int) $2, 
-                                        (Attributes) $1, lexer.Location);
+               new_struct = new Struct (current_namespace, current_container, full_struct_name,
+                                        (int) $2, (Attributes) $1, lexer.Location);
                current_container = new_struct;
-               current_container.Namespace = current_namespace;
-               RootContext.Tree.RecordDecl (full_struct_name, new_struct);
+               RootContext.Tree.RecordDecl (full_struct_name.GetName (true), new_struct);
+               lexer.ConstraintsParsing = true;
          }
          opt_class_base
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+         }
          struct_body
          opt_semicolon
          {
                Struct new_struct = (Struct) current_container;
 
+               CheckDef (new_struct.SetParameterInfo ((ArrayList) $7), new_struct.Name, new_struct.Location);
+
                if ($6 != null)
                        new_struct.Bases = (ArrayList) $6;
 
@@ -676,6 +761,9 @@ struct_declaration
                CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
                $$ = new_struct;
          }
+       | opt_attributes opt_modifiers STRUCT error {
+               CheckIdentifierToken (yyToken);
+         }
        ;
 
 struct_body
@@ -877,12 +965,36 @@ opt_error_modifier
 method_header
        : opt_attributes
          opt_modifiers
-         type
-         member_name
+         type namespace_or_type_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
-               Method method = new Method ((Expression) $3, (int) $2, (string) $4, 
-                                           (Parameters) $6, (Attributes) $1, lexer.Location);
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+
+               MemberName name = (MemberName) $4;
+
+               if ($9 != null && name.TypeArguments == null)
+                       Report.Error (80, lexer.Location,
+                                     "Contraints are not allowed on non-generic declarations");
+
+               Method method;
+
+               GenericMethod generic = null;
+               if (name.TypeArguments != null) {
+                       generic = new GenericMethod (current_namespace, current_container,
+                                                    name, lexer.Location);
+
+                       CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location);
+
+                       method = new Method (generic, (Expression) $3, (int) $2, false, name,
+                                            (Parameters) $6, (Attributes) $1, lexer.Location);
+               } else
+                       method = new Method (current_container, (Expression) $3, (int) $2,
+                                            false, name, (Parameters) $6, (Attributes) $1,
+                                            lexer.Location);
 
                current_local_parameters = (Parameters) $6;
 
@@ -890,12 +1002,55 @@ method_header
          }
        | opt_attributes
          opt_modifiers
-         VOID
-         member_name
+         VOID namespace_or_type_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
-               Method method = new Method (TypeManager.system_void_expr, (int) $2, (string) $4, 
-                                           (Parameters) $6, (Attributes) $1, lexer.Location);
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+
+               MemberName name = (MemberName) $4;
+
+               if ($9 != null && name.TypeArguments == null)
+                       Report.Error (80, lexer.Location,
+                                     "Contraints are not allowed on non-generic declarations");
+
+               Method method;
+               GenericMethod generic = null;
+               if (name.TypeArguments != null) {
+                       generic = new GenericMethod (current_namespace, current_container,
+                                                    name, lexer.Location);
+
+
+                       CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location);
+
+                       method = new Method (generic, TypeManager.system_void_expr, (int) $2,
+                                            false, name, (Parameters) $6, (Attributes) $1,
+                                            lexer.Location);
+               } else
+                       method = new Method (current_container, TypeManager.system_void_expr,
+                                            (int) $2, false, name, (Parameters) $6,
+                                            (Attributes) $1, lexer.Location);
+
+               current_local_parameters = (Parameters) $6;
+
+               $$ = method;
+         }
+       | opt_attributes
+         opt_modifiers
+         type 
+         modifiers namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+         {
+               Report.Error (1585, lexer.Location, 
+                       String.Format ("Modifier {0} should appear before type", 
+                               Modifiers.Name ((int) $4)));
+               MemberName name = (MemberName) $4;
+
+               Method method = new Method (current_container, TypeManager.system_void_expr,
+                                           0, false, name, (Parameters) $6, (Attributes) $1,
+                                           lexer.Location);
 
                current_local_parameters = (Parameters) $6;
                $$ = method;
@@ -931,10 +1086,23 @@ formal_parameter_list
 
                $$ = new Parameters (pars, (Parameter) $3, lexer.Location); 
          }
+       | fixed_parameters COMMA ARGLIST
+         {
+               ArrayList pars_list = (ArrayList) $1;
+
+               Parameter [] pars = new Parameter [pars_list.Count];
+               pars_list.CopyTo (pars);
+
+               $$ = new Parameters (pars, true, lexer.Location);
+         }
        | parameter_array 
          {
                $$ = new Parameters (null, (Parameter) $1, lexer.Location);
          }
+       | ARGLIST
+         {
+               $$ = new Parameters (null, true, lexer.Location);
+         }
        ;
 
 fixed_parameters
@@ -962,6 +1130,13 @@ fixed_parameter
          {
                $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
          }
+       | opt_attributes
+         opt_parameter_modifier
+         type
+         error {
+               CheckIdentifierToken (yyToken);
+               $$ = null;
+         }
        ;
 
 opt_parameter_modifier
@@ -980,16 +1155,16 @@ parameter_array
                $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
                note ("type must be a single-dimension array type"); 
          }
-       ;
-
-member_name 
-       : qualified_identifier
+       | opt_attributes PARAMS type error {
+               CheckIdentifierToken (yyToken);
+               $$ = null;
+         }
        ;
 
 property_declaration
        : opt_attributes
          opt_modifiers
-         type member_name
+         type namespace_or_type_name
          OPEN_BRACE 
          {
                implicit_value_parameter_type = (Expression) $3;
@@ -997,6 +1172,8 @@ property_declaration
                lexer.PropertyParsing = true;
 
                $$ = lexer.Location;
+
+               iterator_container = SimpleIteratorContainer.GetSimple ();
          }
          accessor_declarations 
          {
@@ -1009,12 +1186,19 @@ property_declaration
                Accessor get_block = (Accessor) pair.First;
                Accessor set_block = (Accessor) pair.Second;
 
+               MemberName name = (MemberName) $4;
+               if (name.TypeArguments != null)
+                       syntax_error (lexer.Location, "a property can't have type arguments");
+
                Location loc = (Location) $6;
-               prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block,
-                                    (Attributes) $1, loc);
+               prop = new Property (current_container, (Expression) $3, (int) $2, false,
+                                    name, (Attributes) $1, get_block, set_block, loc);
+               if (SimpleIteratorContainer.Simple.Yields)
+                       prop.SetYields ();
                
                CheckDef (current_container.AddProperty (prop), prop.Name, loc);
                implicit_value_parameter_type = null;
+               iterator_container = null;
          }
        ;
 
@@ -1103,57 +1287,43 @@ accessor_body
 interface_declaration
        : opt_attributes
          opt_modifiers
-         INTERFACE IDENTIFIER
+         INTERFACE member_name
          {
                Interface new_interface;
-               string full_interface_name = MakeName ((string) $4);
+               MemberName full_interface_name = MakeName ((MemberName) $4);
 
-               new_interface = new Interface (current_container, full_interface_name, (int) $2, 
-                                              (Attributes) $1, lexer.Location);
+               new_interface = new Interface (current_namespace, current_container, full_interface_name,
+                                              (int) $2, (Attributes) $1, lexer.Location);
                if (current_interface != null) {
                        Location l = lexer.Location;
                        Report.Error (-2, l, "Internal compiler error: interface inside interface");
                }
                current_interface = new_interface;
-               new_interface.Namespace = current_namespace;
-               RootContext.Tree.RecordDecl (full_interface_name, new_interface);
+               current_container = new_interface;
+               RootContext.Tree.RecordDecl (
+                       full_interface_name.GetName (true), new_interface);
+               lexer.ConstraintsParsing = true;
+         }
+         opt_class_base
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
          }
-         opt_interface_base
          interface_body opt_semicolon
          { 
                Interface new_interface = (Interface) current_interface;
 
+               CheckDef (new_interface.SetParameterInfo ((ArrayList) $7), new_interface.Name, new_interface.Location);
                if ($6 != null)
                        new_interface.Bases = (ArrayList) $6;
 
                current_interface = null;
+               current_container = current_container.Parent;
                CheckDef (current_container.AddInterface (new_interface), 
                          new_interface.Name, new_interface.Location);
          }
-       ;
-
-opt_interface_base
-       : /* empty */                     { $$ = null; }
-       | interface_base
-       ;
-
-interface_base
-       : COLON interface_type_list       { $$ = $2; }
-       ;
-
-interface_type_list
-       : interface_type
-         {
-               ArrayList interfaces = new ArrayList (4);
-
-               interfaces.Add ($1);
-               $$ = interfaces;
-         }
-       | interface_type_list COMMA interface_type
-         {
-               ArrayList interfaces = (ArrayList) $1;
-               interfaces.Add ($3);
-               $$ = interfaces;
+       | opt_attributes opt_modifiers INTERFACE error {
+               CheckIdentifierToken (yyToken);
          }
        ;
 
@@ -1176,50 +1346,101 @@ interface_member_declarations
 interface_member_declaration
        : interface_method_declaration          
          { 
-               InterfaceMethod m = (InterfaceMethod) $1;
+               Method m = (Method) $1;
 
                CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
          }
        | interface_property_declaration        
          { 
-               InterfaceProperty p = (InterfaceProperty) $1;
+               Property p = (Property) $1;
 
                CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
           }
        | interface_event_declaration 
           { 
-               InterfaceEvent e = (InterfaceEvent) $1;
-
-               CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
+               if ($1 != null){
+                       Event e = (Event) $1;
+                       CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
+               }
          }
        | interface_indexer_declaration
          { 
-               InterfaceIndexer i = (InterfaceIndexer) $1;
+               Indexer i = (Indexer) $1;
 
-               CheckDef (current_interface.AddIndexer (i), "indexer", i.Location);
+               current_interface.AddIndexer (i);
          }
        ;
 
 opt_new
-       : /* empty */   { $$ = false; }
-       | NEW           { $$ = true; }
+       : opt_modifiers 
+         {
+               int val = (int) $1;
+               val = Modifiers.Check (Modifiers.NEW | Modifiers.UNSAFE, val, 0, lexer.Location);
+               $$ = val;
+         }
        ;
 
 interface_method_declaration
-       : opt_attributes opt_new type IDENTIFIER 
+       : opt_attributes opt_new type namespace_or_type_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
          SEMICOLON
          {
-               $$ = new InterfaceMethod ((Expression) $3, (string) $4, (bool) $2, 
-                                         (Parameters) $6, (Attributes) $1, lexer.Location);
+               lexer.ConstraintsParsing = false;
+
+               MemberName name = (MemberName) $4;
+
+               if ($9 != null && name.TypeArguments == null)
+                       Report.Error (80, lexer.Location,
+                                     "Contraints are not allowed on non-generic declarations");
+
+               GenericMethod generic = null;
+               if (name.TypeArguments != null) {
+                       generic = new GenericMethod (current_namespace, current_container,
+                                                    name, lexer.Location);
+
+                       CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location);
+
+                       $$ = new Method (generic, (Expression) $3, (int) $2, true, name,
+                                        (Parameters) $6, (Attributes) $1, lexer.Location);
+               } else
+                       $$ = new Method (current_container, (Expression) $3, (int) $2, true,
+                                        name, (Parameters) $6, (Attributes) $1,
+                                        lexer.Location);
          }
-       | opt_attributes opt_new VOID IDENTIFIER 
+       | opt_attributes opt_new VOID namespace_or_type_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
          SEMICOLON
          {
-               $$ = new InterfaceMethod (
-                       TypeManager.system_void_expr, (string) $4, (bool) $2, (Parameters) $6, 
-                                         (Attributes) $1, lexer.Location);
+               lexer.ConstraintsParsing = false;
+
+               MemberName name = (MemberName) $4;
+
+               if ($9 != null && name.TypeArguments == null)
+                       Report.Error (80, lexer.Location,
+                                     "Contraints are not allowed on non-generic declarations");
+
+               GenericMethod generic = null;
+               if (name.TypeArguments != null) {
+                       generic = new GenericMethod (current_namespace, current_container,
+                                                    name, lexer.Location);
+
+                       CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location);
+
+                       $$ = new Method (generic, TypeManager.system_void_expr, (int) $2,
+                                        true, name, (Parameters) $6, (Attributes) $1,
+                                        lexer.Location);
+               } else
+                       $$ = new Method (current_container, TypeManager.system_void_expr,
+                                        (int) $2, true, name, (Parameters) $6,
+                                        (Attributes) $1, lexer.Location);
          }
        ;
 
@@ -1229,33 +1450,52 @@ interface_property_declaration
          type IDENTIFIER 
          OPEN_BRACE 
          { lexer.PropertyParsing = true; }
-         interface_accesors 
+         interface_accessors 
          { lexer.PropertyParsing = false; }
          CLOSE_BRACE
          {
-               int gs = (int) $7;
+                InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7;
 
-               $$ = new InterfaceProperty ((Expression) $3, (string) $4, (bool) $2, 
-                                           (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
-                                           lexer.Location);
+               $$ = new Property (current_container, (Expression) $3, (int) $2, true,
+                                  new MemberName ((string) $4), (Attributes) $1,
+                                  pinfo.Get, pinfo.Set, lexer.Location);
+         }
+       | opt_attributes
+         opt_new
+         type error {
+               CheckIdentifierToken (yyToken);
+               $$ = null;
          }
        ;
 
-interface_accesors
-       : opt_attributes GET SEMICOLON          { $$ = 1; }
-       | opt_attributes SET SEMICOLON          { $$ = 2; }
+interface_accessors
+       : opt_attributes GET SEMICOLON          { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null); }
+       | opt_attributes SET SEMICOLON          { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1); }
        | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON 
-         { $$ = 3; }
+         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3); }
        | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
-         { $$ = 3; }
+         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1); }
        ;
 
 interface_event_declaration
        : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
          {
-               $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
-                                        lexer.Location);
+               $$ = new EventField (current_container, (Expression) $4, (int) $2, true,
+                                    new MemberName ((string) $5), null,
+                                    (Attributes) $1, lexer.Location);
+         }
+       | opt_attributes opt_new EVENT type error {
+               CheckIdentifierToken (yyToken);
+               $$ = null;
          }
+       | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN  {
+               Report.Error (68, lexer.Location, "Event declarations on interfaces can not be initialized.");
+               $$ = null;
+         }
+       | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE event_accessor_declarations CLOSE_BRACE {
+               Report.Error (69, lexer.Location, "Event accessors not valid on interfaces");
+               $$ = null;
+         }
        ;
 
 interface_indexer_declaration 
@@ -1263,32 +1503,38 @@ interface_indexer_declaration
          OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
          OPEN_BRACE 
          { lexer.PropertyParsing = true; }
-         interface_accesors 
+         interface_accessors 
          { lexer.PropertyParsing = false; }
          CLOSE_BRACE
          {
-               int a_flags = (int) $10;
+               InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10;
 
-               bool do_get = (a_flags & 1) == 1;
-               bool do_set = (a_flags & 2) == 2;
-
-               $$ = new InterfaceIndexer ((Expression) $3, (Parameters) $6, do_get, do_set,
-                                          (bool) $2, (Attributes) $1, lexer.Location);
+               $$ = new Indexer (current_container, (Expression) $3, (int) $2, true,
+                                 MemberName.Null, (Parameters) $6, (Attributes) $1,
+                                 info.Get, info.Set, lexer.Location);
          }
        ;
 
 operator_declaration
-       : opt_attributes opt_modifiers operator_declarator operator_body
+       : opt_attributes opt_modifiers operator_declarator 
+         {
+               iterator_container = SimpleIteratorContainer.GetSimple ();
+         }
+         operator_body
          {
                OperatorDeclaration decl = (OperatorDeclaration) $3;
                
                Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name,
-                                           decl.arg2type, decl.arg2name, (Block) $4, (Attributes) $1, decl.location);
+                                           decl.arg2type, decl.arg2name, (Block) $5, (Attributes) $1, decl.location);
+
+               if (SimpleIteratorContainer.Simple.Yields)
+                       op.SetYields ();
 
                // Note again, checking is done in semantic analysis
                current_container.AddOperator (op);
 
                current_local_parameters = null;
+               iterator_container = null;
          }
        ;
 
@@ -1459,7 +1705,8 @@ constructor_declarator
          opt_constructor_initializer
          {
                Location l = (Location) oob_stack.Pop ();
-               $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $6, l);
+               $$ = new Constructor (current_container, (string) $1, 0, (Parameters) $3,
+                                     (ConstructorInitializer) $6, l);
          }
        ;
 
@@ -1513,19 +1760,27 @@ destructor_declaration
                         if ((m & Modifiers.UNSAFE) != 0){
                                 if (!RootContext.Unsafe){
                                         Report.Error (227, l,
-                                             "Unsafe code requires the --unsafe command " +
+                                             "Unsafe code requires the -unsafe command " +
                                              "line option to be specified");
                                 }
                         }
                         
-                       Method d = new Method (
-                               TypeManager.system_void_expr, m, "Finalize", 
+                       Method d = new Destructor (
+                               current_container, TypeManager.system_void_expr, m, "Finalize", 
                                new Parameters (null, null, l), (Attributes) $1, l);
                  
                        d.Block = (Block) $7;
                        CheckDef (current_container.AddMethod (d), d.Name, d.Location);
                }
          }
+       | opt_attributes opt_modifiers EVENT type member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS block {
+               string mn = (string) $5;
+
+               if (mn.IndexOf ('.') != -1)
+                       Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax");
+               else 
+                       Report.Error (71, lexer.Location, "Event declaration should use property syntax");
+         }
        ;
 
 event_declaration
@@ -1535,9 +1790,12 @@ event_declaration
          {
                foreach (VariableDeclaration var in (ArrayList) $5) {
 
-                       Event e = new Event ((Expression) $4, var.identifier, 
-                                            var.expression_or_array_initializer,
-                                            (int) $2, null, null, (Attributes) $1, lexer.Location);
+                       MemberName name = new MemberName (var.identifier);
+
+                       Event e = new EventField (current_container, (Expression) $4, (int) $2,
+                                                 false, name,
+                                                 var.expression_or_array_initializer,
+                                                 (Attributes) $1, lexer.Location);
 
                        CheckDef (current_container.AddEvent (e), e.Name, e.Location);
                                       
@@ -1545,7 +1803,7 @@ event_declaration
          }
        | opt_attributes
          opt_modifiers
-         EVENT type member_name
+         EVENT type namespace_or_type_name
          OPEN_BRACE
          {
                implicit_value_parameter_type = (Expression) $4;  
@@ -1560,21 +1818,25 @@ event_declaration
          {
                Location loc = (Location) oob_stack.Pop ();
 
+               if ($8 == null){
+                       Report.Error (65, lexer.Location, "Event must have both add and remove accesors");
+                       $$ = null;
+               } else {
                Pair pair = (Pair) $8;
-               Accessor add_accessor = null;
-               Accessor rem_accessor = null;
 
-               if (pair.First != null)
-                       add_accessor = (Accessor) pair.First;
-               if (pair.Second != null)
-                       rem_accessor = (Accessor) pair.Second;
-               
-               Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
-                                    (Attributes) $1, loc);
+               MemberName name = (MemberName) $5;
+               if (name.TypeArguments != null)
+                       syntax_error (lexer.Location, "an event can't have type arguments");
+
+               Event e = new EventProperty (current_container, (Expression) $4, (int) $2,
+                                            false, name, null, (Attributes) $1,
+                                            (Accessor) pair.First, (Accessor) pair.Second,
+                                            loc);
                
                CheckDef (current_container.AddEvent (e), e.Name, loc);
                implicit_value_parameter_type = null;
          }
+         }
        ;
 
 event_accessor_declarations
@@ -1586,6 +1848,8 @@ event_accessor_declarations
        {
                $$ = new Pair ($2, $1);
        }       
+       | add_accessor_declaration  { $$ = null; } 
+       | remove_accessor_declaration { $$ = null; } 
        ;
 
 add_accessor_declaration
@@ -1666,8 +1930,15 @@ indexer_declaration
                Accessor get_block = (Accessor) pair.First;
                Accessor set_block = (Accessor) pair.Second;
 
-               indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
-                                      get_block, set_block, (Attributes) $1, loc);
+               MemberName name;
+               if (decl.interface_type != null)
+                       name = new MemberName (decl.interface_type, "", null);
+               else
+                       name = MemberName.Null;
+
+               indexer = new Indexer (current_container, decl.type, (int) $2, false,
+                                      name, decl.param_list, (Attributes) $1,
+                                      get_block, set_block, loc);
 
                // Note that there is no equivalent of CheckDef for this case
                // We shall handle this in semantic analysis
@@ -1691,14 +1962,18 @@ indexer_declarator
 
                $$ = new IndexerDeclaration ((Expression) $1, null, pars);
          }
-       | type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
+       | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
          {
                Parameters pars = (Parameters) $6;
 
                if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
-               $$ = new IndexerDeclaration ((Expression) $1, (string) $2, pars);
+               MemberName name = (MemberName) $2;
+               if (name.TypeArguments != null)
+                       syntax_error (lexer.Location, "an indexer can't have type arguments");
+
+               $$ = new IndexerDeclaration ((Expression) $1, name, pars);
          }
        ;
 
@@ -1712,9 +1987,9 @@ enum_declaration
          { 
                Location enum_location = lexer.Location;
 
-               string full_name = MakeName ((string) $4);
-               Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name, 
-                                  (Attributes) $1, enum_location);
+               MemberName full_name = MakeName (new MemberName ((string) $4));
+               Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
+                                  full_name, (Attributes) $1, enum_location);
                
                foreach (VariableDeclaration ev in (ArrayList) $6) {
                        Location loc = (Location) ev.Location;
@@ -1725,10 +2000,9 @@ enum_declaration
                                  ev.identifier, loc);
                }
 
-               e.Namespace = current_namespace;
-
-               CheckDef (current_container.AddEnum (e), full_name, enum_location);
-               RootContext.Tree.RecordDecl (full_name, e);
+               string name = full_name.GetName (false);
+               CheckDef (current_container.AddEnum (e), name, enum_location);
+               RootContext.Tree.RecordDecl (name, e);
 
          }
        ;
@@ -1786,47 +2060,93 @@ enum_member_declaration
 delegate_declaration
        : opt_attributes
          opt_modifiers
-         DELEGATE type   
-         IDENTIFIER OPEN_PARENS 
-         opt_formal_parameter_list
-         CLOSE_PARENS 
-         SEMICOLON
+         DELEGATE type member_name
+         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          {
                Location l = lexer.Location;
-               Delegate del = new Delegate (current_container, (Expression) $4, (int) $2, 
-                                            MakeName ((string) $5), (Parameters) $7, 
-                                            (Attributes) $1, l);
+               Delegate del = new Delegate (
+                       current_namespace, current_container, (Expression) $4, (int) $2,
+                       MakeName ((MemberName) $5), (Parameters) $7, (Attributes) $1, l);
                  
-               del.Namespace = current_namespace;
                CheckDef (current_container.AddDelegate (del), del.Name, l);
-         }     
+
+               current_delegate = del;
+
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+         }
+         SEMICOLON
+         {
+               CheckDef (current_delegate.SetParameterInfo ((ArrayList) $9), current_delegate.Name, current_delegate.Location);
+
+               current_delegate = null;
+         }
        | opt_attributes
          opt_modifiers
-         DELEGATE VOID   
-         IDENTIFIER OPEN_PARENS 
-         opt_formal_parameter_list
-         CLOSE_PARENS 
-         SEMICOLON
+         DELEGATE VOID member_name
+         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
                Location l = lexer.Location;
                Delegate del = new Delegate (
-                       current_container,
-                       TypeManager.system_void_expr, (int) $2, MakeName ((string) $5), 
+                       current_namespace, current_container,
+                       TypeManager.system_void_expr, (int) $2, MakeName ((MemberName) $5), 
                        (Parameters) $7, (Attributes) $1, l);
 
-               del.Namespace = current_namespace;
                CheckDef (current_container.AddDelegate (del), del.Name, l);
+
+               current_delegate = del;
+
+               lexer.ConstraintsParsing = true;
          }
-       ;
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+         }
+         SEMICOLON
+         {
+               CheckDef (current_delegate.SetParameterInfo ((ArrayList) $9), current_delegate.Name, current_delegate.Location);
 
-type_name
-       : namespace_or_type_name
+               current_delegate = null;
+         }
        ;
 
 namespace_or_type_name
-       : qualified_identifier
+       : member_name
+       | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list {
+               $$ = new MemberName ((MemberName) $1, (string) $3, (TypeArguments) $4);
+         }
+       ;
+
+member_name
+       : IDENTIFIER opt_type_argument_list {
+               $$ = new MemberName ((string) $1, (TypeArguments) $2);
+         }
+       ;
+
+opt_type_argument_list
+       : /* empty */                { $$ = null; } 
+       | OP_GENERICS_LT type_arguments OP_GENERICS_GT
+         {
+               $$ = $2;
+         }
        ;
 
+type_arguments
+       : type {
+               TypeArguments type_args = new TypeArguments (lexer.Location);
+               type_args.Add ((Expression) $1);
+               $$ = type_args;
+         }
+       | type_arguments COMMA type {
+               TypeArguments type_args = (TypeArguments) $1;
+               type_args.Add ((Expression) $3);
+               $$ = type_args;
+         }
+       ;
+       
 /* 
  * Before you think of adding a return_type, notice that we have been
  * using two rules in the places where it matters (one rule using type
@@ -1834,12 +2154,9 @@ namespace_or_type_name
  * gets rid of a shift/reduce couple
  */
 type
-       : type_name {   /* class_type */
-               /* 
-                  This does interfaces, delegates, struct_types, class_types, 
-                  parent classes, and more! 4.2 
-                */
-               $$ = DecomposeQI ((string) $1, lexer.Location);
+       : namespace_or_type_name
+         {
+               $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
          }
        | builtin_types
        | array_type
@@ -1936,10 +2253,6 @@ integral_type
        | VOID          { $$ = TypeManager.system_void_expr; }
        ;
 
-interface_type
-       : type_name
-       ;
-
 array_type
        : type rank_specifiers
          {
@@ -1956,14 +2269,12 @@ primary_expression
                // 7.5.1: Literals
          }
  
-       | qualified_identifier
+       | member_name
          {
-               string name = (string) $1;
-
-               $$ = null;
-               $$ = DecomposeQI (name, lexer.Location);
+               $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
          }
        | parenthesized_expression
+       | default_value_expression
        | member_access
        | invocation_expression
        | element_access
@@ -1999,9 +2310,16 @@ integer_literal
        : LITERAL_INTEGER       { 
                object v = lexer.Value;
 
-               if (v is int)
-                       $$ = new IntLiteral ((Int32) v); 
-               else if (v is uint)
+               if (v is int){
+                       int i = (int) v;
+
+                       if (i == 0)
+                               $$ = IntLiteral.Zero;
+                       else if (i == 1)
+                               $$ = IntLiteral.One;
+                       else
+                               $$ = new IntLiteral (i);
+               } else if (v is uint)
                        $$ = new UIntLiteral ((UInt32) v);
                else if (v is long)
                        $$ = new LongLiteral ((Int64) v);
@@ -2017,19 +2335,41 @@ boolean_literal
        | FALSE                 { $$ = new BoolLiteral (false); }
        ;
 
-parenthesized_expression
+parenthesized_expression_0
        : OPEN_PARENS expression CLOSE_PARENS
-         { $$ = $2; }
+         {
+               $$ = $2;
+               lexer.Deambiguate_CloseParens ();
+               // After this, the next token returned is one of
+               // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS
+               // or CLOSE_PARENS_MINUS.
+         }
        ;
 
+parenthesized_expression
+       : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
+         {
+               $$ = $1;
+         }
+       | parenthesized_expression_0 CLOSE_PARENS_MINUS
+         {
+               // If a parenthesized expression is followed by a minus, we need to wrap
+               // the expression inside a ParenthesizedExpression for the CS0075 check
+               // in Binary.DoResolve().
+               $$ = new ParenthesizedExpression ((Expression) $1, lexer.Location);
+         }
+       ;;
+
 member_access
-       : primary_expression DOT IDENTIFIER
+       : primary_expression DOT IDENTIFIER opt_type_argument_list
          {
-               $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+               $$ = new MemberAccess ((Expression) $1, (string) $3,
+                                      (TypeArguments) $4, lexer.Location);
          }
-       | predefined_type DOT IDENTIFIER
+       | predefined_type DOT IDENTIFIER opt_type_argument_list
          {
-               $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+               $$ = new MemberAccess ((Expression) $1, (string) $3,
+                                      (TypeArguments) $4, lexer.Location);
          }
        ;
 
@@ -2046,9 +2386,13 @@ invocation_expression
                }
                $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
          }
-       | OPEN_PARENS expression CLOSE_PARENS unary_expression
+       | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
+         {
+               $$ = new Invocation ((Expression) $1, new ArrayList (), lexer.Location);
+         }
+       | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
          {
-                 $$ = new InvocationOrCast ((Expression) $2, (Expression) $4, lexer.Location);
+               $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location);
          }
        ;
 
@@ -2070,6 +2414,9 @@ argument_list
                list.Add ($3);
                $$ = list;
          }
+       | argument_list error {
+               CheckToken (1026, yyToken, ", or ) expected");
+         }
        ;
 
 argument
@@ -2085,6 +2432,19 @@ argument
          { 
                $$ = new Argument ((Expression) $2, Argument.AType.Out);
          }
+       | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
+         {
+               ArrayList list = (ArrayList) $3;
+               Argument[] args = new Argument [list.Count];
+               list.CopyTo (args, 0);
+
+               Expression expr = new Arglist (args, lexer.Location);
+               $$ = new Argument (expr, Argument.AType.Expression);
+         }
+       | ARGLIST
+         {
+               $$ = new Argument (new ArglistAccess (lexer.Location), Argument.AType.ArgList);
+         }
        ;
 
 variable_reference
@@ -2104,11 +2464,11 @@ element_access
                // Foo.Bar.Blah i;
                // SimpleName is when you have
                // Blah i;
-                 
+
                Expression expr = (Expression) $1;  
                if (expr is ComposedCast){
                        $$ = new ComposedCast (expr, (string) $2, lexer.Location);
-               } else if (!(expr is SimpleName || expr is MemberAccess)){
+               } else if (!(expr is SimpleName || expr is MemberAccess || expr is ConstructedType)){
                        Error_ExpectingTypeName (lexer.Location, expr);
                        $$ = TypeManager.system_object_expr;
                } else {
@@ -2152,6 +2512,10 @@ base_access
          {
                $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
          }
+       | BASE error {
+               Report.Error (175, "Use of keyword `base' is not valid in this context");
+               $$ = null;
+         }
        ;
 
 post_increment_expression
@@ -2329,13 +2693,21 @@ anonymous_method_expression
        : DELEGATE opt_anonymous_method_signature {
                oob_stack.Push (current_local_parameters);
                current_local_parameters = (Parameters)$2;
+               create_toplevel_block = true;
          } block {
-               if (!RootContext.V2){
-                       Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2");
+               if (true){
+                       Report.Error (-213, lexer.Location, "Anonymous methods are not supported in this branch");
                        $$ = null;
-               } else 
-                       $$ = new AnonymousMethod ((Parameters) $2, (Block) $3, lexer.Location);
-               current_local_parameters = (Parameters) oob_stack.Pop ();
+               } else {
+                       create_toplevel_block = false;
+                       Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2");
+                       if (!RootContext.V2){
+                               Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2");
+                               $$ = null;
+                       } else 
+                               $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location);
+                       current_local_parameters = (Parameters) oob_stack.Pop ();
+               }
          }
        ;
 
@@ -2384,6 +2756,13 @@ anonymous_method_parameter
          }
        ;
 
+default_value_expression
+       : DEFAULT_OPEN_PARENS type CLOSE_PARENS
+         {
+               $$ = new DefaultValueExpression ((Expression) $2, lexer.Location);
+         }
+       ;
+
 unary_expression
        : primary_expression
        | BANG prefixed_unary_expression
@@ -2397,10 +2776,22 @@ unary_expression
        | cast_expression
        ;
 
+cast_list
+       : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
+         {
+               $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
+         {
+               $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
+         }     
+       ;
+
 cast_expression
-       : OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
+       : cast_list
+       | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
          {
-                 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
+               $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
          }
        ;
 
@@ -2696,28 +3087,37 @@ boolean_expression
 class_declaration
        : opt_attributes
          opt_modifiers
-         CLASS IDENTIFIER
+         CLASS member_name
          {
                Class new_class;
-               string name;
 
-               name = MakeName ((string) $4);
+               MemberName name = MakeName ((MemberName) $4);
 
-               new_class = new Class (current_container, name, (int) $2, 
+               new_class = new Class (current_namespace, current_container, name, (int) $2, 
                                       (Attributes) $1, lexer.Location);
                current_container = new_class;
-               current_container.Namespace = current_namespace;
-               RootContext.Tree.RecordDecl (name, new_class);
+               RootContext.Tree.RecordDecl (name.GetName (true), new_class);
+
+               lexer.ConstraintsParsing = true;
          }
          opt_class_base
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+         }
          class_body 
          opt_semicolon 
          {
                Class new_class = (Class) current_container;
 
-               if ($6 != null)
-                       new_class.Bases = (ArrayList) $6;
+               CheckDef (new_class.SetParameterInfo ((ArrayList) $7), new_class.Name, new_class.Location);
+               if ($6 != null) {
+                       if (new_class.Name == "System.Object") {
+                               Report.Error (537, new_class.Location, "The class System.Object cannot have a base class or implement an interface.");
+                       }
 
+                       new_class.Bases = (ArrayList) $6;
+               }
                current_container = current_container.Parent;
                CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
 
@@ -2771,6 +3171,59 @@ class_base
        : COLON type_list { $$ = $2; }
        ;
 
+opt_type_parameter_constraints_clauses
+       : /* empty */           { $$ = null; }
+       | type_parameter_constraints_clauses 
+         { $$ = $1; }
+       ;
+
+type_parameter_constraints_clauses
+       : type_parameter_constraints_clause {
+               ArrayList constraints = new ArrayList (1);
+               constraints.Add ($1);
+               $$ = constraints;
+         }
+       | type_parameter_constraints_clauses type_parameter_constraints_clause {
+               ArrayList constraints = (ArrayList) $1;
+
+               constraints.Add ($2);
+               $$ = constraints;
+         }
+       ; 
+
+type_parameter_constraints_clause
+       : WHERE IDENTIFIER COLON type_parameter_constraints {
+               $$ = new Constraints ((string) $2, (ArrayList) $4, lexer.Location);
+         }
+       ; 
+
+type_parameter_constraints
+       : type_parameter_constraint {
+               ArrayList constraints = new ArrayList (1);
+               constraints.Add ($1);
+               $$ = constraints;
+         }
+       | type_parameter_constraints COMMA type_parameter_constraint {
+               ArrayList constraints = (ArrayList) $1;
+
+               constraints.Add ($3);
+               $$ = constraints;
+         }
+       ;
+
+type_parameter_constraint
+       : type
+       | NEW OPEN_PARENS CLOSE_PARENS {
+               $$ = SpecialConstraint.Constructor;
+         }
+       | CLASS {
+               $$ = SpecialConstraint.ReferenceType;
+         }
+       | STRUCT {
+               $$ = SpecialConstraint.ValueType;
+         }
+       ;
+
 //
 // Statements (8.2)
 //
@@ -2787,8 +3240,12 @@ class_base
 block
        : OPEN_BRACE 
          {
+               if (current_block == null || create_toplevel_block){
+                       current_block = new ToplevelBlock (current_local_parameters, lexer.Location);
+               } else {
                current_block = new Block (current_block, current_local_parameters,
                                           lexer.Location, Location.Null);
+               }
          } 
          opt_statement_list CLOSE_BRACE 
          { 
@@ -2818,17 +3275,14 @@ statement
                        current_block = (Block) $1;
                }
          }
-       | embedded_statement
+       | valid_declaration_statement
          {
-               Statement s = (Statement) $1;
-
-
                current_block.AddStatement ((Statement) $1);
          }
        | labeled_statement
        ;
 
-embedded_statement
+valid_declaration_statement
        : block
        | empty_statement
         | expression_statement
@@ -2844,10 +3298,24 @@ embedded_statement
        | fixed_statement
        ;
 
+embedded_statement
+       : valid_declaration_statement
+       | declaration_statement
+         {
+                 Report.Error (1023, lexer.Location, "An embedded statement may not be a declaration.");
+                 $$ = null;
+         }
+       | labeled_statement
+         {
+                 Report.Error (1023, lexer.Location, "An embedded statement may not be a labeled statement.");
+                 $$ = null;
+         }
+       ;
+
 empty_statement
        : SEMICOLON
          {
-                 $$ = new EmptyStatement ();
+                 $$ = EmptyStatement.Value;
          }
        ;
 
@@ -2856,11 +3324,8 @@ labeled_statement
          {
                LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
 
-               if (!current_block.AddLabel ((string) $1, labeled)){
-                       Location l = lexer.Location;
-                       Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
-               }       
-               current_block.AddStatement (labeled);
+               if (current_block.AddLabel ((string) $1, labeled, lexer.Location))
+                       current_block.AddStatement (labeled);
          }
          statement
        ;
@@ -2880,7 +3345,7 @@ declaration_statement
                if ($1 != null){
                        DictionaryEntry de = (DictionaryEntry) $1;
 
-                       $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+                       $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
                }
          }
        ;
@@ -2899,7 +3364,7 @@ local_variable_type
                // Ok, the above "primary_expression" is there to get rid of
                // both reduce/reduce and shift/reduces in the grammar, it should
                // really just be "type_name".  If you use type_name, a reduce/reduce
-               // creeps up.  If you use qualified_identifier (which is all we need
+               // creeps up.  If you use namespace_or_type_name (which is all we need
                // really) two shift/reduces appear.
                // 
 
@@ -2911,7 +3376,7 @@ local_variable_type
                // Blah i;
                  
                Expression expr = (Expression) $1;  
-               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
+               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType)) {
                        Error_ExpectingTypeName (lexer.Location, expr);
                        $$ = null;
                } else {
@@ -2941,7 +3406,7 @@ local_variable_pointer_type
                Expression expr = (Expression) $1;  
                Location l = lexer.Location;
 
-               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
+               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType)) {
                        Error_ExpectingTypeName (l, expr);
 
                        $$ = null;
@@ -2986,7 +3451,7 @@ local_variable_declaration
        ;
 
 local_constant_declaration
-       : CONST local_variable_type constant_declarator
+       : CONST local_variable_type constant_declarators
          {
                if ($2 != null)
                        $$ = new DictionaryEntry ($2, $3);
@@ -3053,7 +3518,7 @@ if_statement_rest
                $$ = new If ((Expression) $1, (Statement) $3, l);
 
                if (RootContext.WarningLevel >= 3){
-                       if ($3 is EmptyStatement)
+                       if ($3 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
                }
 
@@ -3175,7 +3640,7 @@ while_statement
                $$ = new While ((Expression) $4, (Statement) $6, l);
        
                if (RootContext.WarningLevel >= 3){
-                       if ($6 is EmptyStatement)
+                       if ($6 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
                }
        }
@@ -3250,7 +3715,7 @@ for_statement
                For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
 
                if (RootContext.WarningLevel >= 3){
-                       if ($10 is EmptyStatement)
+                       if ($10 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
                }
 
@@ -3263,7 +3728,7 @@ for_statement
        ;
 
 opt_for_initializer
-       : /* empty */           { $$ = new EmptyStatement (); }
+       : /* empty */           { $$ = EmptyStatement.Value; }
        | for_initializer       
        ;
 
@@ -3278,7 +3743,7 @@ opt_for_condition
        ;
 
 opt_for_iterator
-       : /* empty */           { $$ = new EmptyStatement (); }
+       : /* empty */           { $$ = EmptyStatement.Value; }
        | for_iterator
        ;
 
@@ -3313,7 +3778,7 @@ foreach_statement
          {
                oob_stack.Push (current_block);
 
-               Block foreach_block = new Block (current_block, Block.Flags.Implicit);
+               Block foreach_block = new Block (current_block);
                LocalVariableReference v = null;
                Location l = lexer.Location;
                LocalInfo vi;
@@ -3401,18 +3866,36 @@ throw_statement
        ;
 
 yield_statement 
-       : YIELD expression SEMICOLON
+       : IDENTIFIER RETURN expression SEMICOLON
          {
+               string s = (string) $1;
+               if (s != "yield"){
+                       Report.Error (1003, lexer.Location, "; expected");
+                       $$ = null;
+               }
+               if (!RootContext.V2){
+                       Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode");
+                       $$ = null;
+               }
                if (iterator_container == null){
                        Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
                        $$ = null;
                } else {
                        iterator_container.SetYields ();
-                       $$ = new Yield ((Expression) $2, lexer.Location);
+                       $$ = new Yield ((Expression) $3, lexer.Location); 
                }
          }
-       | YIELD BREAK SEMICOLON
+       | IDENTIFIER BREAK SEMICOLON
          {
+               string s = (string) $1;
+               if (s != "yield"){
+                       Report.Error (1003, lexer.Location, "; expected");
+                       $$ = null;
+               }
+               if (!RootContext.V2){
+                       Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode");
+                       $$ = null;
+               }
                if (iterator_container == null){
                        Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
                        $$ = null;
@@ -3610,10 +4093,7 @@ fixed_statement
          embedded_statement 
          {
                Location l = (Location) oob_stack.Pop ();
-               Block assign_block = (Block) oob_stack.Pop ();
-
-               ArrayList list = (ArrayList) $4;
-               int top = list.Count;
+               oob_stack.Pop ();
 
                $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
          }
@@ -3742,16 +4222,34 @@ public class VariableDeclaration {
        }
 }
 
+/// <summary>
+///  Used to pass around interface property information
+/// </summary>
+public class InterfaceAccessorInfo {
+
+        public readonly Accessor Get, Set;
+
+        public InterfaceAccessorInfo (bool has_get, bool has_set,
+                                      Attributes get_attrs, Attributes set_attrs)
+        {
+               if (has_get)
+                       Get = new Accessor (null, get_attrs);
+               if (has_set)
+                       Set = new Accessor (null, set_attrs);
+        }
+}
+
+
 // <summary>
 //   A class used to hold info about an indexer declarator
 // </summary>
-
 public class IndexerDeclaration {
        public Expression type;
-       public string interface_type;
+       public MemberName interface_type;
        public Parameters param_list;
 
-       public IndexerDeclaration (Expression type, string interface_type, Parameters param_list)
+       public IndexerDeclaration (Expression type, MemberName interface_type,
+                                  Parameters param_list)
        {
                this.type = type;
                this.interface_type = interface_type;
@@ -3759,10 +4257,28 @@ public class IndexerDeclaration {
        }
 }
 
+//
+// We use this when we do not have an object in advance that is an IIteratorContainer
+//
+public class SimpleIteratorContainer : IIteratorContainer {
+       public bool Yields;
+
+       public static SimpleIteratorContainer Simple = new SimpleIteratorContainer ();
+
+       //
+       // Reset and return
+       //
+       public static SimpleIteratorContainer GetSimple () { 
+               Simple.Yields = false;
+               return Simple;
+       }
+
+       public void SetYields () { Yields = true; } 
+}
+
 // <summary>
 //  A class used to hold info about an operator declarator
 // </summary>
-
 public class OperatorDeclaration {
        public Operator.OpType optype;
        public Expression ret_type, arg1type, arg2type;
@@ -3797,19 +4313,19 @@ void Error_ExpectingTypeName (Location l, Expression expr)
 //   Given the @class_name name, it creates a fully qualified name
 //   based on the containing declaration space
 // </summary>
-string 
-MakeName (string class_name)
+MemberName
+MakeName (MemberName class_name)
 {
-       string ns = current_namespace.Name;
-       string container_name = current_container.Name;
+       string ns = current_namespace.FullName;
 
-       if (container_name == ""){
+       if (current_container.Name == ""){
                if (ns != "")
-                       return ns + "." + class_name;
+                       return new MemberName (new MemberName (ns), class_name);
                else
                        return class_name;
-       } else
-               return container_name + "." + class_name;
+       } else {
+               return new MemberName (current_container.MemberName, class_name);
+       }
 }
 
 // <summary>
@@ -3817,13 +4333,13 @@ MakeName (string class_name)
 //   in the current declaration space
 // </summary>
 void 
-CheckDef (AdditionResult result, string name, Location l)
+CheckDef (DeclSpace.AdditionResult result, string name, Location l)
 {
-       if (result == AdditionResult.Success)
+       if (result == DeclSpace.AdditionResult.Success)
                return;
 
        switch (result){
-       case AdditionResult.NameExists:
+       case DeclSpace.AdditionResult.NameExists:
                Report.Error (102, l, "The container `" + current_container.Name + 
                                 "' already contains a definition for `"+
                                 name + "'");
@@ -3834,22 +4350,22 @@ CheckDef (AdditionResult result, string name, Location l)
                // This is handled only for static Constructors, because
                // in reality we handle these by the semantic analysis later
                //
-       case AdditionResult.MethodExists:
+       case DeclSpace.AdditionResult.MethodExists:
                Report.Error (
                        111, l, "Class `"+current_container.Name+
                        "' already defines a member called '" + 
                        name + "' with the same parameter types (more than one default constructor)");
                break;
 
-       case AdditionResult.EnclosingClash:
+       case DeclSpace.AdditionResult.EnclosingClash:
                Report.Error (542, l, "Member names cannot be the same as their enclosing type");
                break;
                
-       case AdditionResult.NotAConstructor:
+       case DeclSpace.AdditionResult.NotAConstructor:
                Report.Error (1520, l, "Class, struct, or interface method must have a return type");
                break;
 
-       case AdditionResult.Error:
+       case DeclSpace.AdditionResult.Error:
                // Error has already been reported.
                break;
        }
@@ -3860,45 +4376,9 @@ CheckDef (bool result, string name, Location l)
 {
        if (result)
                return;
-       CheckDef (AdditionResult.NameExists, name, l);
+       CheckDef (DeclSpace.AdditionResult.NameExists, name, l);
 }
 
-Expression DecomposeQI (string name, Location loc)
-{
-       Expression o;
-
-       if (name.IndexOf ('.') == -1){
-               return new SimpleName (name, loc);
-       } else {
-               int pos = name.LastIndexOf (".");
-               string left = name.Substring (0, pos);
-               string right = name.Substring (pos + 1);
-
-               o = DecomposeQI (left, loc);
-
-               return new MemberAccess (o, right, loc);
-       }
-}
-
-// <summary>
-//  This method is used to get at the complete string representation of
-//  a fully-qualified type name, hiding inside a MemberAccess ;-)
-//  This is necessary because local_variable_type admits primary_expression
-//  as the type of the variable. So we do some extra checking
-// </summary>
-#if false
-string GetQualifiedIdentifier (Expression expr)
-{
-       if (expr is SimpleName)
-               return ((SimpleName)expr).Name;
-       else if (expr is MemberAccess)
-               return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
-       else 
-               throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
-       
-}
-#endif
-
 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
 {
        Block implicit_block;
@@ -3919,10 +4399,9 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
        //
        // int j = 1;  int k = j + 1;
        //
-       if (current_block.Used) {
+       if (current_block.Used)
                implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
-               implicit_block.AddChildVariableNames (current_block);
-       } else
+       else
                implicit_block = current_block;
 
        foreach (VariableDeclaration decl in variable_declarators){
@@ -3963,7 +4442,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
        return implicit_block;
 }
 
-Block declare_local_constant (Expression type, VariableDeclaration decl)
+Block declare_local_constants (Expression type, ArrayList declarators)
 {
        Block implicit_block;
 
@@ -3972,8 +4451,9 @@ Block declare_local_constant (Expression type, VariableDeclaration decl)
        else
                implicit_block = current_block;
 
-       if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
-                                         current_local_parameters, decl.Location))){
+       foreach (VariableDeclaration decl in declarators){
+               implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+                                                 current_local_parameters, decl.Location);
        }
        
        return implicit_block;
@@ -3983,7 +4463,7 @@ void CheckAttributeTarget (string a)
 {
        switch (a) {
 
-       case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
+       case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
                return;
                
        default :
@@ -4070,20 +4550,20 @@ public Tokenizer Lexer {
        }
 }                 
 
-public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines)
+public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
 {
-       current_namespace = new NamespaceEntry (null, file, null);
+       current_namespace = new NamespaceEntry (null, file, null, Location.Null);
        this.name = file.Name;
        this.file = file;
        current_container = RootContext.Tree.Types;
-       current_container.Namespace = current_namespace;
+       current_container.NamespaceEntry = current_namespace;
        oob_stack = new Stack ();
        switch_stack = new Stack ();
 
        lexer = new Tokenizer (reader, file, defines);
 }
 
-public override void parse ()
+public void parse ()
 {
        try {
                if (yacc_verbose_flag)
@@ -4096,10 +4576,26 @@ public override void parse ()
                // Please do not remove this, it is used during debugging
                // of the grammar
                //
-               Report.Error (-25, lexer.Location, ": Parsing error ");
                Console.WriteLine (e);
+               Report.Error (-25, lexer.Location, "Parsing error");
+               if (Driver.parser_verbose)
+                       Console.WriteLine (e);
        }
 }
 
+void CheckToken (int error, int yyToken, string msg)
+{
+       if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){
+               Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()));
+               return;
+       }               
+       Report.Error (error, lexer.Location, msg);
+}
+
+void CheckIdentifierToken (int yyToken)
+{
+       CheckToken (1041, yyToken, "Identifier expected");
+}
+
 /* end end end */
 }