**** Merged r45106 from MCS ****
[mono.git] / mcs / gmcs / cs-parser.jay
old mode 100755 (executable)
new mode 100644 (file)
index c769b58..06a28d3
@@ -8,6 +8,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 // TODO:
 //   (1) Figure out why error productions dont work.  `type-declaration' is a
@@ -40,13 +41,7 @@ namespace Mono.CSharp
                ///   Current block is used to add statements as we find
                ///   them.  
                /// </summary>
-               Block      current_block;
-
-               /// <summary>
-                ///   If true, creates a toplevel block in the block production
-                ///   This is flagged by the delegate creation
-                /// </summary>
-                bool       create_toplevel_block;
+               Block      current_block, top_current_block;
 
                Delegate   current_delegate;
 
@@ -80,7 +75,7 @@ namespace Mono.CSharp
                ///
                Stack switch_stack;
 
-               public bool yacc_verbose_flag;
+               static public int yacc_verbose_flag;
 
                // Name of the file we are parsing
                public string name;
@@ -89,13 +84,21 @@ namespace Mono.CSharp
                /// The current file.
                ///
                SourceFile file;
-               
-               
+
+               ///
+               /// Temporary Xml documentation cache.
+               /// For enum types, we need one more temporary store.
+               ///
+               string tmpComment;
+               string enumTypeComment;
+                       
                /// Current attribute target
                string current_attr_target;
                
                /// assembly and module attribute definition is enabled
                bool global_attrs_enabled = true;
+               bool has_get, has_set;
+
 %}
 
 %token EOF
@@ -296,7 +299,13 @@ compilation_unit
        
 opt_EOF
        : /* empty */
+       {
+               Lexer.check_incorrect_doc_comment ();
+       }
        | EOF
+       {
+               Lexer.check_incorrect_doc_comment ();
+       }
        ;
 
 outer_declarations
@@ -316,7 +325,15 @@ using_directives
 
 using_directive
        : using_alias_directive
+       {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+       }
        | using_namespace_directive
+       {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+       }
        ;
 
 using_alias_directive
@@ -333,7 +350,7 @@ using_alias_directive
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((string) $2, lexer.Location);
+               current_namespace.Using ((MemberName) $2, lexer.Location);
           }
        ;
 
@@ -346,19 +363,13 @@ namespace_declaration
        : opt_attributes NAMESPACE namespace_or_type_name
        {
                if ($1 != null) {
-                       Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
-                                       + " Expected class, delegate, enum, interface, or struct");
+                       Report.Error(1671, Lexer.Location, "A namespace declaration cannot have modifiers or attributes");
                }
 
                MemberName name = (MemberName) $3;
 
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "namespace name expected");
-               else if ((current_namespace.Parent != null) && (name.Left != null)) {
-                       Report.Error (134, lexer.Location,
-                                     "Cannot use qualified namespace names in nested " +
-                                     "namespace declarations");
-               }
 
                current_namespace = new NamespaceEntry (
                        current_namespace, file, name.GetName (), lexer.Location);
@@ -386,17 +397,19 @@ namespace_name
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "namespace name expected");
 
-               $$ = name.GetName ();
+               $$ = name;
          }
        ;
 
 namespace_body
        : OPEN_BRACE
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_using_directives
          opt_namespace_member_declarations
          CLOSE_BRACE
-         {
-         }
        ;
 
 opt_using_directives
@@ -417,25 +430,13 @@ namespace_member_declarations
 namespace_member_declaration
        : type_declaration
          {
-               string name = "";
-               int mod_flags;
-
-               if ($1 is Class){
-                       Class c = (Class) $1;
-                       mod_flags = c.ModFlags;
-                       name = c.Name;
-               } else if ($1 is Struct){
-                       Struct s = (Struct) $1;
-                       mod_flags = s.ModFlags;
-                       name = s.Name;
-               } else
-                       break;
+               if ($1 != null) {
+                       DeclSpace ds = (DeclSpace)$1;
 
-               if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
-                       Report.Error (
-                               1527, lexer.Location, 
-                               "Namespace elements cant be explicitly " +
-                               "declared private or protected in `" + name + "'");
+                       if ((ds.ModFlags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+                               Report.Error (1527, lexer.Location, 
+                               "Namespace elements cannot be explicitly declared as private, protected or protected internal");
+                       }
                }
                current_namespace.DeclarationFound = true;
          }
@@ -508,6 +509,13 @@ attribute_sections
                        } else {
                                $$ = new Attributes (sect);
                        }
+                       if ($$ == null) {
+                               if (RootContext.Documentation != null) {
+                                       Lexer.check_incorrect_doc_comment ();
+                                       Lexer.doc_state =
+                                               XmlCommentState.Allowed;
+                               }
+                       }
                } else {
                        $$ = new Attributes (sect);
                }               
@@ -596,19 +604,23 @@ attribute
          }
          opt_attribute_arguments
          {
+               Location loc = (Location) $2;
                MemberName mname = (MemberName) $1;
                if (mname.IsGeneric) {
                        Report.Error (404, lexer.Location,
                                      "'<' unexpected: attributes cannot be generic");
                }
 
-               string name = mname.GetName ();
+               MemberName left = mname.Left;
+               string identifier = mname.Name;
+
+               Expression left_expr = left == null ? null : left.GetTypeExpression (loc);
+
                if (current_attr_target == "assembly" || current_attr_target == "module")
-                       $$ = new GlobalAttribute (current_container, current_attr_target,
-                                                 name, (ArrayList) $3, (Location) $2);
+                       $$ = new GlobalAttribute (current_class, current_attr_target,
+                                                 left_expr, identifier, (ArrayList) $3, loc);
                else
-                       $$ = new Attribute (current_attr_target, name, (ArrayList) $3,
-                                           (Location) $2);
+                       $$ = new Attribute (current_attr_target, left_expr, identifier, (ArrayList) $3, loc);
          }
        ;
 
@@ -693,6 +705,11 @@ named_argument_list
 
                $$ = args;
          }
+         | named_argument_list COMMA expression
+           {
+                 Report.Error (1016, lexer.Location, "Named attribute argument expected");
+                 $$ = null;
+               }
         ;
 
 named_argument
@@ -737,48 +754,53 @@ struct_declaration
        : opt_attributes
          opt_modifiers
          opt_partial
-         STRUCT member_name
+         STRUCT
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         member_name
          { 
-               MemberName name = MakeName ((MemberName) $5);
+               MemberName name = MakeName ((MemberName) $6);
                bool partial = (bool) $3;
 
                if (partial) {
                        ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, Kind.Struct, lexer.Location);
 
                        current_container = part.PartialContainer;
                        current_class = part;
                } else {
                        current_class = new Struct (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, lexer.Location);
 
+                       current_container.AddClassOrStruct (current_class);
                        current_container = current_class;
-                       RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+                       RootContext.Tree.RecordDecl (name, current_class);
                }
-
-               lexer.ConstraintsParsing = true;
          }
          opt_class_base
          opt_type_parameter_constraints_clauses
          {
                lexer.ConstraintsParsing = false;
 
-               if ($7 != null)
-                       current_class.Bases = (ArrayList) $7;
+               if ($8 != null)
+                       current_class.Bases = (ArrayList) $8;
 
-               current_class.SetParameterInfo ((ArrayList) $8);
+               current_class.SetParameterInfo ((ArrayList) $9);
 
-               current_class.Register ();
+               if (RootContext.Documentation != null)
+                       current_class.DocComment = Lexer.consume_doc_comment ();
          }
          struct_body
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_semicolon
          {
-               $$ = current_class;
-
-               current_container = current_container.Parent;
-               current_class = current_container;
+               $$ = pop_current_class ();
          }
        | opt_attributes opt_modifiers opt_partial STRUCT error {
                CheckIdentifierToken (yyToken);
@@ -786,7 +808,12 @@ struct_declaration
        ;
 
 struct_body
-       : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
+       : OPEN_BRACE
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_struct_member_declarations CLOSE_BRACE
        ;
 
 opt_struct_member_declarations
@@ -838,6 +865,10 @@ constant_declaration
                                (Expression) constant.expression_or_array_initializer, modflags, 
                                (Attributes) $1, l);
 
+                       if (RootContext.Documentation != null) {
+                               c.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
                        current_container.AddConstant (c);
                }
          }
@@ -884,15 +915,38 @@ field_declaration
                int mod = (int) $2;
 
                foreach (VariableDeclaration var in (ArrayList) $4){
-                       Location l = var.Location;
-
                        Field field = new Field (current_class, type, mod, var.identifier, 
                                                 var.expression_or_array_initializer, 
-                                                (Attributes) $1, l);
+                                                (Attributes) $1, var.Location);
 
+                       if (RootContext.Documentation != null) {
+                               field.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
                        current_container.AddField (field);
                }
          }
+       | opt_attributes
+         opt_modifiers
+         FIXED
+         type 
+         fixed_variable_declarators
+         SEMICOLON
+         { 
+                       Expression type = (Expression) $4;
+                       int mod = (int) $2;
+
+                       foreach (VariableDeclaration var in (ArrayList) $5) {
+                               FixedField field = new FixedField (current_class, type, mod, var.identifier,
+                                       (Expression)var.expression_or_array_initializer, (Attributes) $1, var.Location);
+
+                               if (RootContext.Documentation != null) {
+                                       field.DocComment = Lexer.consume_doc_comment ();
+                                       Lexer.doc_state = XmlCommentState.Allowed;
+                               }
+                               current_container.AddField (field);
+                       }
+         }
        | opt_attributes
          opt_modifiers
          VOID  
@@ -902,11 +956,34 @@ field_declaration
          }
        ;
 
+fixed_variable_declarators
+       : fixed_variable_declarator
+               {
+                       ArrayList decl = new ArrayList (2);
+                       decl.Add ($1);
+                       $$ = decl;
+               }
+       | fixed_variable_declarators COMMA fixed_variable_declarator
+               {
+                       ArrayList decls = (ArrayList) $1;
+                       decls.Add ($3);
+                       $$ = $1;
+               }
+       ;
+
+fixed_variable_declarator
+       : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET
+               {
+                       $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
+               }
+       ;
+
 variable_declarators
        : variable_declarator 
          {
                ArrayList decl = new ArrayList (4);
-               decl.Add ($1);
+               if ($1 != null)
+                       decl.Add ($1);
                $$ = decl;
          }
        | variable_declarators COMMA variable_declarator
@@ -926,6 +1003,12 @@ variable_declarator
          {
                $$ = new VariableDeclaration ((string) $1, null, lexer.Location);
          }
+       | IDENTIFIER OPEN_BRACKET opt_expression CLOSE_BRACKET
+         {
+               Report.Error (650, lexer.Location, "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " +
+                       "To declare a fixed size buffer field, use the fixed keyword before the field type");
+               $$ = null;
+         }
        ;
 
 variable_initializer
@@ -941,11 +1024,18 @@ variable_initializer
          {
                $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
          }
+       | STACKALLOC type
+         {
+               Report.Error (1575, lexer.Location, "A stackalloc expression requires [] after type");
+                $$ = null;
+         }
        ;
 
 method_declaration
        : method_header {
                iterator_container = (IIteratorContainer) $1;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
          }
          method_body
          {
@@ -967,30 +1057,14 @@ method_declaration
                        }
                }
 
-               method.Block = (Block) $3;
+               method.Block = (ToplevelBlock) $3;
                current_container.AddMethod (method);
 
                current_local_parameters = null;
                iterator_container = null;
-         }
-       ;
 
-opt_error_modifier
-       : /* empty */
-       | modifiers 
-         {
-               int m = (int) $1;
-               int i = 1;
-
-               while (m != 0){
-                       if ((i & m) != 0){
-                               Report.Error (
-                                       1585, lexer.Location, "Member modifier `" + 
-                                       Modifiers.Name (i) + "' must precede member type and name");
-                       }
-                       m &= ~i;
-                       i = i << 1;
-               }
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
@@ -1027,6 +1101,9 @@ method_header
 
                current_local_parameters = (Parameters) $6;
 
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        | opt_attributes
@@ -1060,6 +1137,10 @@ method_header
                                     lexer.Location);
 
                current_local_parameters = (Parameters) $6;
+
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        | opt_attributes
@@ -1077,6 +1158,10 @@ method_header
                                            lexer.Location);
 
                current_local_parameters = (Parameters) $6;
+
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        ;
@@ -1099,7 +1184,7 @@ formal_parameter_list
                Parameter [] pars = new Parameter [pars_list.Count];
                pars_list.CopyTo (pars);
 
-               $$ = new Parameters (pars, null, lexer.Location); 
+               $$ = new Parameters (pars, null); 
          } 
        | fixed_parameters COMMA parameter_array
          {
@@ -1108,7 +1193,7 @@ formal_parameter_list
                Parameter [] pars = new Parameter [pars_list.Count];
                pars_list.CopyTo (pars);
 
-               $$ = new Parameters (pars, (Parameter) $3, lexer.Location); 
+               $$ = new Parameters (pars, (Parameter) $3); 
          }
        | fixed_parameters COMMA ARGLIST
          {
@@ -1117,15 +1202,25 @@ formal_parameter_list
                Parameter [] pars = new Parameter [pars_list.Count];
                pars_list.CopyTo (pars);
 
-               $$ = new Parameters (pars, true, lexer.Location);
+               $$ = new Parameters (pars, true);
+         }
+       | parameter_array COMMA fixed_parameters
+         {
+               Report.Error (231, lexer.Location, "A params parameter must be the last parameter in a formal parameter list");
+               $$ = null;
+         }
+       | ARGLIST COMMA fixed_parameters
+         {
+               Report.Error (257, lexer.Location, "An __arglist parameter must be the last parameter in a formal parameter list");
+               $$ = null;
          }
        | parameter_array 
          {
-               $$ = new Parameters (null, (Parameter) $1, lexer.Location);
+               $$ = new Parameters (null, (Parameter) $1);
          }
        | ARGLIST
          {
-               $$ = new Parameters (null, true, lexer.Location);
+               $$ = new Parameters (null, true);
          }
        ;
 
@@ -1152,7 +1247,22 @@ fixed_parameter
          type
          IDENTIFIER
          {
-               $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
+               $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1, lexer.Location);
+         }
+       | opt_attributes
+         opt_parameter_modifier
+         type
+         IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
+         {
+               Report.Error (1552, lexer.Location, "Array type specifier, [], must appear before parameter name");
+               $$ = null;
+         }
+       | opt_attributes
+         opt_parameter_modifier
+         type
+         {
+               Report.Error (1001, lexer.Location, "Identifier expected");
+               $$ = null;
          }
        | opt_attributes
          opt_parameter_modifier
@@ -1186,9 +1296,14 @@ parameter_modifier
 parameter_array
        : opt_attributes PARAMS type IDENTIFIER
          { 
-               $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
+               $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1, lexer.Location);
                note ("type must be a single-dimension array type"); 
          }
+       | opt_attributes PARAMS parameter_modifier type IDENTIFIER 
+         {
+               Report.Error (1611, lexer.Location, "The params parameter cannot be declared as ref or out");
+                $$ = null;
+         }
        | opt_attributes PARAMS type error {
                CheckIdentifierToken (yyToken);
                $$ = null;
@@ -1198,7 +1313,12 @@ parameter_array
 property_declaration
        : opt_attributes
          opt_modifiers
-         type namespace_or_type_name
+         type
+         namespace_or_type_name
+         {
+               if (RootContext.Documentation != null)
+                       tmpComment = Lexer.consume_doc_comment ();
+         }
          OPEN_BRACE 
          {
                implicit_value_parameter_type = (Expression) $3;
@@ -1212,21 +1332,25 @@ property_declaration
          accessor_declarations 
          {
                lexer.PropertyParsing = false;
+               has_get = has_set = false;
          }
          CLOSE_BRACE
          { 
+               if ($8 == null)
+                       break;
+
                Property prop;
-               Pair pair = (Pair) $7;
+               Pair pair = (Pair) $8;
                Accessor get_block = (Accessor) pair.First;
                Accessor set_block = (Accessor) pair.Second;
 
-               Location loc = (Location) $6;
+               Location loc = (Location) $7;
                MemberName name = (MemberName) $4;
 
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "a property can't have type arguments");
 
-               prop = new Property (current_container, (Expression) $3, (int) $2, false,
+               prop = new Property (current_class, (Expression) $3, (int) $2, false,
                                     name, (Attributes) $1, get_block, set_block, loc);
                if (SimpleIteratorContainer.Simple.Yields)
                        prop.SetYields ();
@@ -1234,32 +1358,43 @@ property_declaration
                current_container.AddProperty (prop);
                implicit_value_parameter_type = null;
                iterator_container = null;
+
+               if (RootContext.Documentation != null)
+                       prop.DocComment = ConsumeStoredComment ();
+
          }
        ;
 
 accessor_declarations
-       : get_accessor_declaration opt_set_accessor_declaration
-         { 
-               $$ = new Pair ($1, $2);
-         }
-       | set_accessor_declaration opt_get_accessor_declaration
+       : get_accessor_declaration
+        {
+               $$ = new Pair ($1, null);
+        }
+       | get_accessor_declaration accessor_declarations
+        { 
+               Pair pair = (Pair) $2;
+               pair.First = $1;
+               $$ = pair;
+        }
+       | set_accessor_declaration
+        {
+               $$ = new Pair (null, $1);
+        }
+       | set_accessor_declaration accessor_declarations
+        { 
+               Pair pair = (Pair) $2;
+               pair.Second = $1;
+               $$ = pair;
+        }
+       | error
          {
-               $$ = new Pair ($2, $1);
+               Report.Error (1014, lexer.Location, "A get or set accessor expected");
+               $$ = null;
          }
        ;
 
-opt_get_accessor_declaration
-       : /* empty */                   { $$ = null; }
-       | get_accessor_declaration
-       ;
-
-opt_set_accessor_declaration
-       : /* empty */                   { $$ = null; }
-       | set_accessor_declaration
-       ;
-
 get_accessor_declaration
-       : opt_attributes GET
+       : opt_attributes opt_modifiers GET
          {
                // If this is not the case, then current_local_parameters has already
                // been set in indexer_declaration
@@ -1271,24 +1406,33 @@ get_accessor_declaration
          }
           accessor_body
          {
-               $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
+               if (has_get) {
+                       Report.Error (1007, lexer.Location, "Property accessor already defined");
+                       break;
+               }
+               $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
+               has_get = true;
                current_local_parameters = null;
                lexer.PropertyParsing = true;
+
+               if (RootContext.Documentation != null)
+                       if (Lexer.doc_state == XmlCommentState.Error)
+                               Lexer.doc_state = XmlCommentState.NotAllowed;
          }
        ;
 
 set_accessor_declaration
-       : opt_attributes SET 
+       : opt_attributes opt_modifiers SET 
          {
                Parameter [] args;
                Parameter implicit_value_parameter = new Parameter (
                        implicit_value_parameter_type, "value", 
-                       Parameter.Modifier.NONE, null);
+                       Parameter.Modifier.NONE, null, lexer.Location);
 
                if (parsing_indexer == false) {
                        args  = new Parameter [1];
                        args [0] = implicit_value_parameter;
-                       current_local_parameters = new Parameters (args, null, lexer.Location);
+                       current_local_parameters = new Parameters (args, null);
                } else {
                        Parameter [] fpars = indexer_parameters.FixedParameters;
 
@@ -1301,16 +1445,25 @@ set_accessor_declaration
                        } else 
                                args = null;
                        current_local_parameters = new Parameters (
-                               args, indexer_parameters.ArrayParameter, lexer.Location);
+                               args, indexer_parameters.ArrayParameter);
                }
                
                lexer.PropertyParsing = false;
          }
          accessor_body
          {
-               $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
+               if (has_set) {
+                       Report.Error (1007, lexer.Location, "Property accessor already defined");
+                       break;
+               }
+               $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
+               has_set = true;
                current_local_parameters = null;
                lexer.PropertyParsing = true;
+
+               if (RootContext.Documentation != null
+                       && Lexer.doc_state == XmlCommentState.Error)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
          }
        ;
 
@@ -1323,47 +1476,55 @@ interface_declaration
        : opt_attributes
          opt_modifiers
          opt_partial
-         INTERFACE member_name
+         INTERFACE
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         member_name
          {
-               MemberName name = MakeName ((MemberName) $5);
+               MemberName name = MakeName ((MemberName) $6);
                bool partial = (bool) $3;
 
                if (partial) {
                        ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, Kind.Interface, lexer.Location);
 
                        current_container = part.PartialContainer;
                        current_class = part;
                } else {
                        current_class = new Interface (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, lexer.Location);
 
+                       current_container.AddInterface (current_class);
                        current_container = current_class;
-                       RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+                       RootContext.Tree.RecordDecl (name, current_class);
                }
-
-               lexer.ConstraintsParsing = true;
          }
          opt_class_base
          opt_type_parameter_constraints_clauses
          {
                lexer.ConstraintsParsing = false;
 
-               if ($7 != null)
-                       current_class.Bases = (ArrayList) $7;
+               if ($8 != null)
+                       current_class.Bases = (ArrayList) $8;
 
-               current_class.SetParameterInfo ((ArrayList) $8);
+               current_class.SetParameterInfo ((ArrayList) $9);
 
-               current_class.Register ();
+               if (RootContext.Documentation != null) {
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
          }
-         interface_body opt_semicolon
+         interface_body
          { 
-               $$ = current_class;
-
-               current_container = current_container.Parent;
-               current_class = current_container;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_semicolon 
+         {
+               $$ = pop_current_class ();
          }
        | opt_attributes opt_modifiers opt_partial INTERFACE error {
                CheckIdentifierToken (yyToken);
@@ -1389,28 +1550,90 @@ interface_member_declarations
 interface_member_declaration
        : interface_method_declaration          
          { 
+               if ($1 == null)
+                       break;
+
                Method m = (Method) $1;
 
+               if (m.IsExplicitImpl)
+                       Report.Error (541, lexer.Location, 
+                               "Explicit interface declaration can only be declared in a class or struct");
+
                current_container.AddMethod (m);
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        | interface_property_declaration        
          { 
+               if ($1 == null)
+                       break;
+
                Property p = (Property) $1;
 
+               if (p.IsExplicitImpl)
+                       Report.Error (541, lexer.Location, 
+                               "Explicit interface declaration can only be declared in a class or struct");
+
                current_container.AddProperty (p);
-          }
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
        | interface_event_declaration 
           { 
                if ($1 != null){
                        Event e = (Event) $1;
+
+                       if (e.IsExplicitImpl)
+                               Report.Error (541, lexer.Location, 
+                                   "Explicit interface declaration can only be declared in a class or struct");
+                       
                        current_container.AddEvent (e);
                }
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        | interface_indexer_declaration
          { 
+               if ($1 == null)
+                       break;
+
                Indexer i = (Indexer) $1;
 
+               if (i.IsExplicitImpl)
+                       Report.Error (541, lexer.Location, 
+                               "Explicit interface declaration can only be declared in a class or struct");
+
                current_container.AddIndexer (i);
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+       | delegate_declaration
+         {
+               Report.Error (524, lexer.Location, "Interfaces can not declare delegates");
+         }
+       | class_declaration
+         {
+               Report.Error (524, lexer.Location, "Interfaces can not declare classes");
+         }
+       | struct_declaration
+         {
+               Report.Error (524, lexer.Location, "Interfaces can not declare structures");
+         }
+       | enum_declaration 
+         {
+               Report.Error (524, lexer.Location, "Interfaces can not declare enumerations");
+         }
+       | interface_declaration 
+         {
+               Report.Error (524, lexer.Location, "Interfaces can not declare interfaces");
+         } 
+       | constant_declaration
+         {
+               Report.Error (525, lexer.Location, "Interfaces cannot contain constants");
          }
        ;
 
@@ -1450,6 +1673,8 @@ interface_method_declaration
 
                $$ = new Method (current_class, generic, (Expression) $3, (int) $2, true, name,
                                 (Parameters) $6, (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Method) $$).DocComment = Lexer.consume_doc_comment ();
          }
        | opt_attributes opt_new VOID namespace_or_type_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
@@ -1477,7 +1702,22 @@ interface_method_declaration
 
                $$ = new Method (current_class, generic, TypeManager.system_void_expr, (int) $2,
                                 true, name, (Parameters) $6, (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Method) $$).DocComment = Lexer.consume_doc_comment ();
          }
+       | 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
+         OPEN_BRACE opt_statement_list CLOSE_BRACE
+         {
+               lexer.ConstraintsParsing = false;
+               Report.Error (531, lexer.Location, "'{0}': interface members cannot have a definition", $4);
+               $$ = null;
+         }
+
        ;
 
 interface_property_declaration
@@ -1490,11 +1730,21 @@ interface_property_declaration
          { lexer.PropertyParsing = false; }
          CLOSE_BRACE
          {
+               if ($3 == TypeManager.system_void_expr) {
+                       Report.Error (547, lexer.Location, "'{0}': property cannot have void type", $4);
+                       break;
+               }
+
+               if ($7 == null)
+                       break;
+
                 InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7;
 
                $$ = new Property (current_class, (Expression) $3, (int) $2, true,
                                   new MemberName ((string) $4), (Attributes) $1,
                                   pinfo.Get, pinfo.Set, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Property) $$).DocComment = Lexer.consume_doc_comment ();
          }
        | opt_attributes
          opt_new
@@ -1505,12 +1755,23 @@ interface_property_declaration
        ;
 
 interface_accessors
-       : opt_attributes GET SEMICOLON          { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, lexer.Location, lexer.Location); }
-       | opt_attributes SET SEMICOLON          { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, lexer.Location, lexer.Location); }
-       | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON 
-         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3, lexer.Location, lexer.Location); }
-       | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
-         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1, lexer.Location, lexer.Location); }
+       : opt_attributes opt_modifiers GET SEMICOLON    
+       { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, (int) $2, 0, lexer.Location, lexer.Location); }
+       | opt_attributes opt_modifiers GET OPEN_BRACE
+        {  
+               Report.Error (531, lexer.Location, "'{0}': interface members cannot have a definition", ".get");
+               $$ = null;
+        }
+       | opt_attributes opt_modifiers SET SEMICOLON            
+       { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, 0, (int) $2, lexer.Location, lexer.Location); }
+       | opt_attributes opt_modifiers GET SEMICOLON opt_attributes opt_modifiers SET SEMICOLON 
+         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $5, (int) $2, (int) $6, lexer.Location, lexer.Location); }
+       | opt_attributes opt_modifiers SET SEMICOLON opt_attributes opt_modifiers GET SEMICOLON
+         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $5, (Attributes) $1, (int) $6, (int) $2, lexer.Location, lexer.Location); }
+       |
+         {
+               Report.Error (548, lexer.Location, "'{0}' : property or indexer must have at least one accessor", "");
+         }
        ;
 
 interface_event_declaration
@@ -1519,6 +1780,8 @@ interface_event_declaration
                $$ = new EventField (current_class, (Expression) $4, (int) $2, true,
                                     new MemberName ((string) $5), null,
                                     (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((EventField) $$).DocComment = Lexer.consume_doc_comment ();
          }
        | opt_attributes opt_new EVENT type error {
                CheckIdentifierToken (yyToken);
@@ -1528,8 +1791,16 @@ interface_event_declaration
                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");
+       | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE
+       {
+               lexer.EventParsing = true;
+       }
+       event_accessor_declarations
+       {
+               lexer.EventParsing = false;
+       }
+       CLOSE_BRACE {
+               Report.Error (69, lexer.Location, "Event in interface cannot have add or remove accessors");
                $$ = null;
          }
        ;
@@ -1543,12 +1814,17 @@ interface_indexer_declaration
          { lexer.PropertyParsing = false; }
          CLOSE_BRACE
          {
+               if ($10 == null)
+                       break;
+
                InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10;
 
                $$ = new Indexer (current_class, (Expression) $3,
                                  new MemberName (TypeContainer.DefaultIndexerName),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
                                  info.Get, info.Set, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Indexer) $$).DocComment = ConsumeStoredComment ();
          }
        ;
 
@@ -1559,18 +1835,26 @@ operator_declaration
          }
          operator_body
          {
+               if ($3 == null)
+                       break;
+
                OperatorDeclaration decl = (OperatorDeclaration) $3;
                
                Parameter [] param_list = new Parameter [decl.arg2type != null ? 2 : 1];
 
-               param_list[0] = new Parameter (decl.arg1type, decl.arg1name, Parameter.Modifier.NONE, null);
+               param_list[0] = new Parameter (decl.arg1type, decl.arg1name, Parameter.Modifier.NONE, null, decl.location);
                if (decl.arg2type != null)
-                       param_list[1] = new Parameter (decl.arg2type, decl.arg2name, Parameter.Modifier.NONE, null);
+                       param_list[1] = new Parameter (decl.arg2type, decl.arg2name, Parameter.Modifier.NONE, null, decl.location);
 
                Operator op = new Operator (
                        current_class, decl.optype, decl.ret_type, (int) $2, 
-                       new Parameters (param_list, null, decl.location),
-                       (Block) $5, (Attributes) $1, decl.location);
+                       new Parameters (param_list, null),
+                       (ToplevelBlock) $5, (Attributes) $1, decl.location);
+
+               if (RootContext.Documentation != null) {
+                       op.DocComment = tmpComment;
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
 
                if (SimpleIteratorContainer.Simple.Yields)
                        op.SetYields ();
@@ -1601,12 +1885,18 @@ operator_declarator
                        op = Operator.OpType.UnaryNegation;
 
                Parameter [] pars = new Parameter [1];
+               Expression type = (Expression) $5;
 
-               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter (type, (string) $6, Parameter.Modifier.NONE, null, lexer.Location);
 
-               current_local_parameters = new Parameters (pars, null, lexer.Location);
+               current_local_parameters = new Parameters (pars, null);
+
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
 
-               $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
+               $$ = new OperatorDeclaration (op, (Expression) $1, type, (string) $6,
                                              null, null, lexer.Location);
        }
        | type OPERATOR overloadable_operator
@@ -1615,20 +1905,44 @@ operator_declarator
                type IDENTIFIER 
          CLOSE_PARENS
         {
-              CheckBinaryOperator ((Operator.OpType) $3);
+               CheckBinaryOperator ((Operator.OpType) $3);
 
-              Parameter [] pars = new Parameter [2];
+               Parameter [] pars = new Parameter [2];
 
-              pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
-              pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
+               Expression typeL = (Expression) $5;
+               Expression typeR = (Expression) $8;
 
-              current_local_parameters = new Parameters (pars, null, lexer.Location);
+              pars [0] = new Parameter (typeL, (string) $6, Parameter.Modifier.NONE, null, lexer.Location);
+              pars [1] = new Parameter (typeR, (string) $9, Parameter.Modifier.NONE, null, lexer.Location);
+
+              current_local_parameters = new Parameters (pars, null);
+
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
               
               $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, 
-                                            (Expression) $5, (string) $6,
-                                            (Expression) $8, (string) $9, lexer.Location);
+                                            typeL, (string) $6,
+                                            typeR, (string) $9, lexer.Location);
         }
        | conversion_operator_declarator
+       | type OPERATOR overloadable_operator
+         OPEN_PARENS 
+               type IDENTIFIER COMMA
+               type IDENTIFIER COMMA
+               type IDENTIFIER
+         CLOSE_PARENS
+       {
+               Report.Error (1534, lexer.Location, "Overloaded binary operator '{0}' takes two parameters", $3);
+               $$ = null;
+       }
+       | type OPERATOR overloadable_operator 
+         OPEN_PARENS CLOSE_PARENS
+       {
+               Report.Error (1535, lexer.Location, "Overloaded unary operator '{0}' takes one parameter", $3);
+               $$ = null;
+       }
        ;
 
 overloadable_operator
@@ -1664,10 +1978,15 @@ conversion_operator_declarator
          {
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null, lexer.Location);
 
-               current_local_parameters = new Parameters (pars, null, lexer.Location);  
+               current_local_parameters = new Parameters (pars, null);  
                  
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+
                $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
          }
@@ -1675,10 +1994,15 @@ conversion_operator_declarator
          {
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null, lexer.Location);
 
-               current_local_parameters = new Parameters (pars, null, lexer.Location);  
+               current_local_parameters = new Parameters (pars, null);  
                  
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+
                $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
          }
@@ -1699,10 +2023,13 @@ constructor_declaration
          constructor_body
          { 
                Constructor c = (Constructor) $3;
-               c.Block = (Block) $4;
+               c.Block = (ToplevelBlock) $4;
                c.OptAttributes = (Attributes) $1;
                c.ModFlags = (int) $2;
        
+               if (RootContext.Documentation != null)
+                       c.DocComment = ConsumeStoredComment ();
+
                if (c.Name == current_container.Basename){
                        if ((c.ModFlags & Modifiers.STATIC) != 0){
                                if ((c.ModFlags & Modifiers.Accessibility) != 0){
@@ -1736,22 +2063,27 @@ constructor_declaration
                current_container.AddConstructor (c);
 
                current_local_parameters = null;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
 constructor_declarator
-       : IDENTIFIER 
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
+       : IDENTIFIER
          {
-               oob_stack.Push (lexer.Location);
-
-               current_local_parameters = (Parameters) $3;
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+         }
+         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS _mark_
+         {
+               current_local_parameters = (Parameters) $4;
          }
          opt_constructor_initializer
          {
-               Location l = (Location) oob_stack.Pop ();
-               $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $3,
-                                     (ConstructorInitializer) $6, l);
+               $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $4,
+                                     (ConstructorInitializer) $8, (Location) $6);
          }
        ;
 
@@ -1768,11 +2100,11 @@ opt_constructor_initializer
 constructor_initializer
        : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
+               $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location);
          }
        | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
+               $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location);
          }
        | COLON error {
                Report.Error (1018, lexer.Location, "Keyword this or base expected");
@@ -1787,11 +2119,18 @@ opt_finalizer
         ;
         
 destructor_declaration
-       : opt_attributes opt_finalizer TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
+       : opt_attributes opt_finalizer TILDE 
          {
-               if ((string) $4 != current_container.Basename){
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+         }
+         IDENTIFIER OPEN_PARENS CLOSE_PARENS block
+         {
+               if ((string) $5 != current_container.MemberName.Name){
                        Report.Error (574, lexer.Location, "Name of destructor must match name of class");
-               } else if (!(current_container is Class)){
+               } else if (current_container.Kind != Kind.Class){
                        Report.Error (575, lexer.Location, "Destructors are only allowed in class types");
                } else {
                        Location l = lexer.Location;
@@ -1812,9 +2151,11 @@ destructor_declaration
                         
                        Method d = new Destructor (
                                current_class, TypeManager.system_void_expr, m, "Finalize", 
-                               new Parameters (null, null, l), (Attributes) $1, l);
+                               new Parameters (null, null), (Attributes) $1, l);
+                       if (RootContext.Documentation != null)
+                               d.DocComment = ConsumeStoredComment ();
                  
-                       d.Block = (Block) $7;
+                       d.Block = (ToplevelBlock) $8;
                        current_container.AddMethod (d);
                }
          }
@@ -1835,17 +2176,20 @@ event_declaration
                                lexer.Location);
 
                        current_container.AddEvent (e);
-                                      
+
+                       if (RootContext.Documentation != null) {
+                               e.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
                }
          }
        | opt_attributes
          opt_modifiers
          EVENT type namespace_or_type_name
-         OPEN_BRACE
+         OPEN_BRACE _mark_
          {
                implicit_value_parameter_type = (Expression) $4;  
                lexer.EventParsing = true;
-               oob_stack.Push (lexer.Location);
          }
          event_accessor_declarations
          {
@@ -1853,13 +2197,13 @@ event_declaration
          }
          CLOSE_BRACE
          {
-               Location loc = (Location) oob_stack.Pop ();
+               Location loc = (Location) $7;
 
-               if ($8 == null){
+               if ($9 == null){
                        Report.Error (65, lexer.Location, "Event must have both add and remove accesors");
                        $$ = null;
                } else {
-                       Pair pair = (Pair) $8;
+                       Pair pair = (Pair) $9;
                        
                        MemberName name = (MemberName) $5;
 
@@ -1870,7 +2214,11 @@ event_declaration
                                current_class, (Expression) $4, (int) $2, false, name, null,
                                (Attributes) $1, (Accessor) pair.First, (Accessor) pair.Second,
                                loc);
-                       
+                       if (RootContext.Documentation != null) {
+                               e.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
+
                        current_container.AddEvent (e);
                        implicit_value_parameter_type = null;
                }
@@ -1882,6 +2230,9 @@ event_declaration
                        Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax");
                else 
                        Report.Error (71, lexer.Location, "Event declaration should use property syntax");
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
@@ -1896,6 +2247,12 @@ event_accessor_declarations
        }       
        | add_accessor_declaration  { $$ = null; } 
        | remove_accessor_declaration { $$ = null; } 
+       | error
+       { 
+               Report.Error (1055, lexer.Location, "An add or remove accessor expected");
+               $$ = null;
+       }
+       | { $$ = null; }
        ;
 
 add_accessor_declaration
@@ -1904,22 +2261,26 @@ add_accessor_declaration
                Parameter [] args = new Parameter [1];
                Parameter implicit_value_parameter = new Parameter (
                        implicit_value_parameter_type, "value", 
-                       Parameter.Modifier.NONE, null);
+                       Parameter.Modifier.NONE, null, lexer.Location);
 
                args [0] = implicit_value_parameter;
                
-               current_local_parameters = new Parameters (args, null, lexer.Location);  
+               current_local_parameters = new Parameters (args, null);  
                lexer.EventParsing = false;
          }
           block
          {
-               $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
+               $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location);
                lexer.EventParsing = true;
          }
        | opt_attributes ADD error {
                Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
                $$ = null;
          }
+       | opt_attributes modifiers ADD {
+               Report.Error (1609, lexer.Location, "Modifiers cannot be placed on event accessor declarations");
+               $$ = null;
+         }
        ;
 
 remove_accessor_declaration
@@ -1928,27 +2289,31 @@ remove_accessor_declaration
                Parameter [] args = new Parameter [1];
                Parameter implicit_value_parameter = new Parameter (
                        implicit_value_parameter_type, "value", 
-                       Parameter.Modifier.NONE, null);
+                       Parameter.Modifier.NONE, null, lexer.Location);
 
                args [0] = implicit_value_parameter;
                
-               current_local_parameters = new Parameters (args, null, lexer.Location);  
+               current_local_parameters = new Parameters (args, null);  
                lexer.EventParsing = false;
          }
           block
          {
-               $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location);
+               $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location);
                lexer.EventParsing = true;
          }
        | opt_attributes REMOVE error {
                Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
                $$ = null;
          }
+       | opt_attributes modifiers REMOVE {
+               Report.Error (1609, lexer.Location, "Modifiers cannot be placed on event accessor declarations");
+               $$ = null;
+         }
        ;
 
 indexer_declaration
        : opt_attributes opt_modifiers indexer_declarator 
-         OPEN_BRACE 
+         OPEN_BRACE _mark_
          {
                IndexerDeclaration decl = (IndexerDeclaration) $3;
 
@@ -1958,21 +2323,24 @@ indexer_declaration
                parsing_indexer  = true;
                
                indexer_parameters = decl.param_list;
-               oob_stack.Push (lexer.Location);
          }
           accessor_declarations 
          {
                  lexer.PropertyParsing = false;
+                 has_get = has_set = false;
                  parsing_indexer  = false;
          }
          CLOSE_BRACE
          { 
+               if ($7 == null)
+                       break;
+
                // The signature is computed from the signature of the indexer.  Look
                // at section 3.6 on the spec
-               Location loc = (Location) oob_stack.Pop ();
+               Location loc = (Location) $5;
                Indexer indexer;
                IndexerDeclaration decl = (IndexerDeclaration) $3;
-               Pair pair = (Pair) $6;
+               Pair pair = (Pair) $7;
                Accessor get_block = (Accessor) pair.First;
                Accessor set_block = (Accessor) pair.Second;
 
@@ -1986,6 +2354,8 @@ indexer_declaration
                indexer = new Indexer (current_class, decl.type, name,
                                       (int) $2, false, decl.param_list, (Attributes) $1,
                                       get_block, set_block, loc);
+               if (RootContext.Documentation != null)
+                       indexer.DocComment = ConsumeStoredComment ();
 
                current_container.AddIndexer (indexer);
                
@@ -2005,6 +2375,10 @@ indexer_declarator
                } else if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
 
                $$ = new IndexerDeclaration ((Expression) $1, null, pars);
          }
@@ -2018,37 +2392,56 @@ indexer_declarator
                } else if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
+
                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);
+
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
          }
        ;
 
 enum_declaration
        : opt_attributes
          opt_modifiers
+         opt_partial
          ENUM IDENTIFIER 
-         opt_enum_base
+         opt_enum_base {
+               if (RootContext.Documentation != null)
+                       enumTypeComment = Lexer.consume_doc_comment ();
+         }
          enum_body
          opt_semicolon
-         { 
+         {
+               bool partial = (bool) $3;
+
+               if (partial) {
+                       Report.Error (267, lexer.Location, "The partial modifier can only appear before a 'class', 'struct', or 'interface'");
+                       break;  // assumes that the parser put us in a switch
+               }
+
                Location enum_location = lexer.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);
+               MemberName name = MakeName (new MemberName ((string) $5));
+               Enum e = new Enum (current_namespace, current_class, (Expression) $6, (int) $2,
+                                  name, (Attributes) $1, enum_location);
                
-               foreach (VariableDeclaration ev in (ArrayList) $6) {
+               if (RootContext.Documentation != null)
+                       e.DocComment = enumTypeComment;
+
+               foreach (VariableDeclaration ev in (ArrayList) $8) {
                        e.AddEnumMember (ev.identifier, 
                                         (Expression) ev.expression_or_array_initializer,
-                                        ev.Location, ev.OptAttributes);
+                                        ev.Location, ev.OptAttributes,
+                                        ev.DocComment);
                }
 
-               string name = full_name.GetName ();
                current_container.AddEnum (e);
                RootContext.Tree.RecordDecl (name, e);
+               $$ = e;
 
          }
        ;
@@ -2059,9 +2452,20 @@ opt_enum_base
        ;
 
 enum_body
-       : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE
+       : OPEN_BRACE
          {
-               $$ = $2;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_enum_member_declarations
+         {
+               // here will be evaluated after CLOSE_BLACE is consumed.
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         CLOSE_BRACE
+         {
+               $$ = $3;
          }
        ;
 
@@ -2091,35 +2495,58 @@ enum_member_declarations
 enum_member_declaration
        : opt_attributes IDENTIFIER 
          {
-               $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+               VariableDeclaration vd = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+
+               if (RootContext.Documentation != null) {
+                       vd.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
+               $$ = vd;
          }
        | opt_attributes IDENTIFIER
          {
-                 $$ = lexer.Location;
+               $$ = lexer.Location;
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
          }
           ASSIGN expression
          { 
-               $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
+               VariableDeclaration vd = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
+
+               if (RootContext.Documentation != null)
+                       vd.DocComment = ConsumeStoredComment ();
+
+               $$ = vd;
          }
        ;
 
 delegate_declaration
        : opt_attributes
          opt_modifiers
-         DELEGATE type member_name
+         DELEGATE
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         type member_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          {
                Location l = lexer.Location;
-               MemberName name = MakeName ((MemberName) $5);
-               Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
-                                            (int) $2, name, (Parameters) $7, (Attributes) $1, l);
+               MemberName name = MakeName ((MemberName) $6);
+               Delegate del = new Delegate (current_namespace, current_class, (Expression) $5,
+                                            (int) $2, name, (Parameters) $8, (Attributes) $1, l);
+
+               if (RootContext.Documentation != null) {
+                       del.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
 
                current_container.AddDelegate (del);
-               RootContext.Tree.RecordDecl (name.GetName (true), del);
+               RootContext.Tree.RecordDecl (name, del);
 
                current_delegate = del;
-
-               lexer.ConstraintsParsing = true;
          }
          opt_type_parameter_constraints_clauses
          {
@@ -2127,38 +2554,23 @@ delegate_declaration
          }
          SEMICOLON
          {
-               current_delegate.SetParameterInfo ((ArrayList) $9);
+               current_delegate.SetParameterInfo ((ArrayList) $10);
+               $$ = current_delegate;
 
                current_delegate = null;
          }
-       | opt_attributes
-         opt_modifiers
-         DELEGATE VOID member_name
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
-         {
-               Location l = lexer.Location;
-               MemberName name = MakeName ((MemberName) $5);
-               Delegate del = new Delegate (
-                       current_namespace, current_container,
-                       TypeManager.system_void_expr, (int) $2, name,
-                       (Parameters) $7, (Attributes) $1, l);
-
-               current_container.AddDelegate (del);
-               RootContext.Tree.RecordDecl (name.GetName (true), del);
-
-               current_delegate = del;
+       ;
 
-               lexer.ConstraintsParsing = true;
-         }
-         opt_type_parameter_constraints_clauses
+opt_nullable
+       : /* empty */
          {
-               lexer.ConstraintsParsing = false;
+               lexer.CheckNullable (false);
+               $$ = false;
          }
-         SEMICOLON
+       | INTERR
          {
-               current_delegate.SetParameterInfo ((ArrayList) $9);
-
-               current_delegate = null;
+               lexer.CheckNullable (true);
+               $$ = true;
          }
        ;
 
@@ -2207,16 +2619,22 @@ type_arguments
  * gets rid of a shift/reduce couple
  */
 type
-       : namespace_or_type_name
+       : namespace_or_type_name opt_nullable
          {
                $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
+
+               if ((bool) $2)
+                       $$ = new ComposedCast ((Expression) $$, "?", lexer.Location);
+         }
+       | builtin_types opt_nullable
+         {
+               if ((bool) $2)
+                       $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
          }
-       | builtin_types
        | array_type
-       | pointer_type    
+       | pointer_type
        ;
 
-
 pointer_type
        : type STAR
          {
@@ -2234,7 +2652,11 @@ pointer_type
        ;
 
 non_expression_type
-       : builtin_types 
+       : builtin_types opt_nullable
+         {
+               if ((bool) $2)
+                       $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
+         }
        | non_expression_type rank_specifier
          {
                $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
@@ -2307,9 +2729,13 @@ integral_type
        ;
 
 array_type
-       : type rank_specifiers
+       : type rank_specifiers opt_nullable
          {
-               $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+               string rank_specifiers = (string) $2;
+               if ((bool) $3)
+                       rank_specifiers += "?";
+
+               $$ = new ComposedCast ((Expression) $1, rank_specifiers, lexer.Location);
          }
        ;
 
@@ -2321,8 +2747,7 @@ primary_expression
          {
                // 7.5.1: Literals
          }
-       | member_name
+       | member_name
          {
                $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
          }
@@ -2447,6 +2872,18 @@ invocation_expression
          {
                $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location);
          }
+       | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS
+         {
+               ArrayList args = new ArrayList (1);
+               args.Add ($4);
+               $$ = new Invocation ((Expression) $1, args, lexer.Location);
+         }
+       | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS
+         {
+               ArrayList args = ((ArrayList) $4);
+               args.Add ($6);
+               $$ = new Invocation ((Expression) $1, args, lexer.Location);
+         }
        ;
 
 opt_argument_list
@@ -2477,7 +2914,14 @@ argument
          {
                $$ = new Argument ((Expression) $1, Argument.AType.Expression);
          }
-       | REF variable_reference 
+       | non_simple_argument
+         {
+               $$ = $1;
+         }
+       ;
+
+non_simple_argument
+       : REF variable_reference 
          { 
                $$ = new Argument ((Expression) $2, Argument.AType.Ref);
          }
@@ -2610,6 +3054,11 @@ array_creation_expression
          {
                $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
          }
+       | NEW error
+         {
+               Report.Error (1031, lexer.Location, "Type expected");
+                $$ = null;
+         }          
        | NEW type error 
          {
                Report.Error (1526, lexer.Location, "new expression requires () or [] after type");
@@ -2627,6 +3076,31 @@ opt_rank_specifier
          }
        ;
 
+opt_rank_specifier_or_nullable
+       : /* empty */
+         {
+               $$ = "";
+         }
+       | INTERR
+         {
+               $$ = "?";
+         }
+       | opt_nullable rank_specifiers
+         {
+               if ((bool) $1)
+                       $$ = "?" + $2;
+               else
+                       $$ = $2;
+         }
+       | opt_nullable rank_specifiers INTERR
+         {
+               if ((bool) $1)
+                       $$ = "?" + $2 + "?";
+               else
+                       $$ = $2 + "?";
+         }
+       ;
+
 rank_specifiers
        : rank_specifier opt_rank_specifier
          {
@@ -2701,11 +3175,26 @@ variable_initializer_list
          }
        ;
 
+void_pointer_expression
+       : void_pointer_expression STAR
+         {
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+         }
+       | VOID STAR
+         {
+               $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
+         }
+       ;
+
 typeof_expression
        : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
          {
                $$ = new TypeOfVoid (lexer.Location);
          }
+       | TYPEOF OPEN_PARENS void_pointer_expression CLOSE_PARENS
+         {
+               $$ = new TypeOf ((Expression) $3, lexer.Location);
+         }
        | TYPEOF OPEN_PARENS
          {
                lexer.TypeOfParsing = true;
@@ -2748,28 +3237,37 @@ pointer_member_access
        ;
 
 anonymous_method_expression
-       : DELEGATE opt_anonymous_method_signature {
+       : DELEGATE opt_anonymous_method_signature _mark_
+         {
                oob_stack.Push (current_local_parameters);
                current_local_parameters = (Parameters)$2;
-               create_toplevel_block = true;
-         } block {
-               if (true){
-                       Report.Error (-213, lexer.Location, "Anonymous methods are not supported in this branch");
-                       $$ = null;
-               } else {
-                       create_toplevel_block = false;
-                       if (RootContext.Version == LanguageVersion.ISO_1){
+
+               // Force the next block to be created as a ToplevelBlock
+               oob_stack.Push (current_block);
+               oob_stack.Push (top_current_block);
+               current_block = null;
+         } 
+         block
+         {
+               Location loc = (Location) $3;
+               top_current_block = (Block) oob_stack.Pop ();
+               current_block = (Block) oob_stack.Pop ();
+               if (RootContext.Version == LanguageVersion.ISO_1){
                                Report.FeatureIsNotStandardized (lexer.Location, "anonymous methods");
                                $$ = null;
-                       } else 
-                               $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location);
+               } else  {
+                       ToplevelBlock anon_block = (ToplevelBlock) $5;
+
+                       anon_block.Parent = current_block;
+                       $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block, 
+                               anon_block, loc);
+               }
                        current_local_parameters = (Parameters) oob_stack.Pop ();
                }
-         }
        ;
 
 opt_anonymous_method_signature
-       : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
+       : /* empty */                   { $$ = null; } 
        | anonymous_method_signature
        ;
 
@@ -2782,7 +3280,7 @@ anonymous_method_signature
                        ArrayList par_list = (ArrayList) $2;
                        Parameter [] pars = new Parameter [par_list.Count];
                        par_list.CopyTo (pars);
-                       $$ = new Parameters (pars, null, lexer.Location);
+                       $$ = new Parameters (pars, null);
                }
          }
        ;
@@ -2809,7 +3307,11 @@ anonymous_method_parameter_list
 
 anonymous_method_parameter
        : opt_parameter_modifier type IDENTIFIER {
-               $$ = new Parameter ((Expression) $2, (string) $2, (Parameter.Modifier) $1, null);
+               $$ = new Parameter ((Expression) $2, (string) $3, (Parameter.Modifier) $1, null, lexer.Location);
+         }
+       | PARAMS type IDENTIFIER {
+               Report.Error (1670, lexer.Location, "params modifier not allowed in anonymous method declaration");
+               $$ = null;
          }
        ;
 
@@ -2949,6 +3451,28 @@ shift_expression
          }
        ; 
 
+opt_error
+       : /* empty */
+         {
+               $$ = false;
+         }
+       | error
+         {
+               lexer.PutbackNullable ();
+               $$ = true;
+         }
+       ;
+
+nullable_type_or_conditional
+       : type opt_error
+         {
+               if (((bool) $2) && ($1 is ComposedCast))
+                       $$ = ((ComposedCast) $1).RemoveNullable ();
+               else
+                       $$ = $1;
+         }
+       ;
+
 relational_expression
        : shift_expression
        | relational_expression OP_LT shift_expression
@@ -2971,13 +3495,19 @@ relational_expression
                $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | relational_expression IS type
+       | relational_expression IS
+         {
+               yyErrorFlag = 3;
+         } nullable_type_or_conditional
          {
-               $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Is ((Expression) $1, (Expression) $4, lexer.Location);
          }
-       | relational_expression AS type
+       | relational_expression AS
          {
-               $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
+               yyErrorFlag = 3;
+         } nullable_type_or_conditional
+         {
+               $$ = new As ((Expression) $1, (Expression) $4, lexer.Location);
          }
        ;
 
@@ -3046,6 +3576,16 @@ conditional_expression
          {
                $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5, lexer.Location);
          }
+       | conditional_or_expression INTERR INTERR expression
+         {
+               $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $4, lexer.Location);
+         }
+       // We'll be resolved into a `parenthesized_expression_0' later on.
+       | conditional_or_expression INTERR CLOSE_PARENS
+         {
+               $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
+               lexer.PutbackCloseParens ();
+         }
        ;
 
 assignment_expression
@@ -3145,15 +3685,19 @@ class_declaration
        : opt_attributes
          opt_modifiers
          opt_partial
-         CLASS member_name
+         CLASS
          {
-               MemberName name = MakeName ((MemberName) $5);
+               lexer.ConstraintsParsing = true;
+         }
+         member_name
+         {
+               MemberName name = MakeName ((MemberName) $6);
                bool partial = (bool) $3;
                int mod_flags = (int) $2;
 
                if (partial) {
                        ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_container, name, mod_flags,
+                               current_namespace, current_class, name, mod_flags,
                                (Attributes) $1, Kind.Class, lexer.Location);
 
                        current_container = part.PartialContainer;
@@ -3161,45 +3705,48 @@ class_declaration
                } else {
                        if ((mod_flags & Modifiers.STATIC) != 0) {
                                current_class = new StaticClass (
-                                       current_namespace, current_container, name,
+                                       current_namespace, current_class, name,
                                        mod_flags, (Attributes) $1, lexer.Location);
                        } else {
                                current_class = new Class (
-                                       current_namespace, current_container, name,
+                                       current_namespace, current_class, name,
                                        mod_flags, (Attributes) $1, lexer.Location);
                        }
 
+                       current_container.AddClassOrStruct (current_class);
                        current_container = current_class;
-                       RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+                       RootContext.Tree.RecordDecl (name, current_class);
                }
-
-               lexer.ConstraintsParsing = true;
          }
          opt_class_base
          opt_type_parameter_constraints_clauses
          {
                lexer.ConstraintsParsing = false;
 
-               if ($7 != null) {
+               if ($8 != null) {
                        if (current_class.Name == "System.Object") {
                                Report.Error (537, current_class.Location,
                                              "The class System.Object cannot have a base " +
                                              "class or implement an interface.");
                        }
-                       current_class.Bases = (ArrayList) $7;
+                       current_class.Bases = (ArrayList) $8;
                }
 
-               current_class.SetParameterInfo ((ArrayList) $8);
+               current_class.SetParameterInfo ((ArrayList) $9);
 
-               current_class.Register ();
+               if (RootContext.Documentation != null) {
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+         }
+         class_body
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
-         class_body 
          opt_semicolon 
          {
-               $$ = current_class;
-
-               current_container = current_container.Parent;
-               current_class = current_container;
+               $$ = pop_current_class ();
          }
        ;       
 
@@ -3325,11 +3872,11 @@ type_parameter_constraint
 block
        : OPEN_BRACE 
          {
-               if (current_block == null || create_toplevel_block){
-                       current_block = new ToplevelBlock (current_local_parameters, lexer.Location);
+               if (current_block == null){
+                       current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
+                       top_current_block = current_block;
                } else {
-               current_block = new Block (current_block, current_local_parameters,
-                                          lexer.Location, Location.Null);
+                       current_block = new Block (current_block, lexer.Location, Location.Null);
                }
          } 
          opt_statement_list CLOSE_BRACE 
@@ -3339,6 +3886,8 @@ block
                $$ = current_block;
                current_block.SetEndLocation (lexer.Location);
                current_block = current_block.Parent;
+               if (current_block == null)
+                       top_current_block = null;
          }
        ;
 
@@ -3442,7 +3991,7 @@ declaration_statement
  * > The expressions are converted into types during semantic analysis.
  */
 local_variable_type
-       : primary_expression opt_rank_specifier
+       : primary_expression opt_rank_specifier_or_nullable
          { 
                // FIXME: Do something smart here regarding the composition of the type.
 
@@ -3476,7 +4025,7 @@ local_variable_type
                                $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
                }
          }
-       | builtin_types opt_rank_specifier
+       | builtin_types opt_rank_specifier_or_nullable
          {
                if ((string) $2 == "")
                        $$ = $1;
@@ -3520,7 +4069,7 @@ local_variable_declaration
                else
                        $$ = null;
          }
-        | local_variable_pointer_type opt_rank_specifier variable_declarators
+        | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators
        {
                if ($1 != null){
                        Expression t;
@@ -3581,52 +4130,37 @@ selection_statement
        ; 
 
 if_statement
-       : if_statement_open if_statement_rest
-         {
-               $$ = $2;
-         }
-       ;
-
-if_statement_open
-       : IF OPEN_PARENS 
-         {
-               oob_stack.Push (lexer.Location);
-         }
-       ;
-
-if_statement_rest
-       : boolean_expression CLOSE_PARENS 
+       : IF OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS 
          embedded_statement
          { 
-               Location l = (Location) oob_stack.Pop ();
+               Location l = (Location) $3;
 
-               $$ = new If ((Expression) $1, (Statement) $3, l);
+               $$ = new If ((Expression) $4, (Statement) $6, l);
 
-               if (RootContext.WarningLevel >= 3){
-                       if ($3 == EmptyStatement.Value)
+               if (RootContext.WarningLevel >= 4){
+                       if ($6 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
                }
 
          }
-       | boolean_expression CLOSE_PARENS
+       | IF OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS
          embedded_statement ELSE embedded_statement
          {
-               Location l = (Location) oob_stack.Pop ();
+               Location l = (Location) $3;
 
-               $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l);
+               $$ = new If ((Expression) $4, (Statement) $6, (Statement) $8, l);
          }
        ;
 
 switch_statement
-       : SWITCH OPEN_PARENS 
+       : SWITCH OPEN_PARENS _mark_
          { 
-               oob_stack.Push (lexer.Location);
                switch_stack.Push (current_block);
          }
          expression CLOSE_PARENS 
          switch_block
          {
-               $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ());
+               $$ = new Switch ((Expression) $5, (ArrayList) $7, (Location) $3);
                current_block = (Block) switch_stack.Pop ();
          }
        ;
@@ -3715,16 +4249,12 @@ iteration_statement
        ;
 
 while_statement
-       : WHILE OPEN_PARENS 
+       : WHILE OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS embedded_statement
        {
-               oob_stack.Push (lexer.Location);
-       }
-       boolean_expression CLOSE_PARENS embedded_statement
-       {
-               Location l = (Location) oob_stack.Pop ();
+               Location l = (Location) $3;
                $$ = new While ((Expression) $4, (Statement) $6, l);
        
-               if (RootContext.WarningLevel >= 3){
+               if (RootContext.WarningLevel >= 4){
                        if ($6 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
                }
@@ -3733,12 +4263,9 @@ while_statement
 
 do_statement
        : DO embedded_statement 
-         WHILE OPEN_PARENS {
-               oob_stack.Push (lexer.Location);
-         }
-         boolean_expression CLOSE_PARENS SEMICOLON
+         WHILE OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS SEMICOLON
          {
-               Location l = (Location) oob_stack.Pop ();
+               Location l = (Location) $5;
 
                $$ = new Do ((Statement) $2, (Expression) $6, l);
          }
@@ -3746,7 +4273,7 @@ do_statement
 
 for_statement
        : FOR OPEN_PARENS 
-         opt_for_initializer SEMICOLON
+         opt_for_initializer SEMICOLON _mark_
          {
                Block assign_block = new Block (current_block);
                current_block = assign_block;
@@ -3761,8 +4288,7 @@ for_statement
 
                                LocalInfo vi;
 
-                               vi = current_block.AddVariable (
-                                       type, decl.identifier, current_local_parameters, decl.Location);
+                               vi = current_block.AddVariable (type, decl.identifier, decl.Location);
                                if (vi == null)
                                        continue;
 
@@ -3787,20 +4313,23 @@ for_statement
                                }
                        }
                        
-                       $3 = null;
-               } 
-               oob_stack.Push (lexer.Location);
+                       // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
+                       // This can be referred to as $6 below.
+                       $$ = null;
+               } else {
+                       $$ = $3;
+               }
          } 
          opt_for_condition SEMICOLON
          opt_for_iterator CLOSE_PARENS 
          embedded_statement
          {
-               Location l = (Location) oob_stack.Pop ();
+               Location l = (Location) $5;
 
-               For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
+               For f = new For ((Statement) $6, (Expression) $7, (Statement) $9, (Statement) $11, l);
 
-               if (RootContext.WarningLevel >= 3){
-                       if ($10 == EmptyStatement.Value)
+               if (RootContext.WarningLevel >= 4){
+                       if ($11 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
                }
 
@@ -3855,46 +4384,47 @@ statement_expression_list
        ;
 
 foreach_statement
-       : FOREACH OPEN_PARENS type IDENTIFIER IN 
-         {
-               oob_stack.Push (lexer.Location);
-         }
+       : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS
+       {
+               Report.Error (230, lexer.Location, "Type and identifier are both required in a foreach statement");
+               $$ = null;
+       }
+       | FOREACH OPEN_PARENS type IDENTIFIER IN _mark_
          expression CLOSE_PARENS 
          {
-               oob_stack.Push (current_block);
-
                Block foreach_block = new Block (current_block);
-               LocalVariableReference v = null;
+               current_block = foreach_block;
+
                Location l = lexer.Location;
                LocalInfo vi;
 
-               vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
+               vi = foreach_block.AddVariable ((Expression) $3, (string) $4, l);
                if (vi != null) {
-                       vi.ReadOnly = true;
+                       vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
 
                        // Get a writable reference to this read-only variable.
-                       v = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
+                       //
+                       // Note that the $$ here refers to the value of _this_ code block,
+                       // not the value of the LHS non-terminal.  This can be referred to as $9 below.
+                       $$ = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
+               } else {
+                       $$ = null;
                }
-               current_block = foreach_block;
-
-               oob_stack.Push (v);
-               oob_stack.Push (current_block);
          } 
          embedded_statement 
          {
-               Block foreach_block = (Block) oob_stack.Pop ();
-               LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
-               Block prev_block = (Block) oob_stack.Pop ();
-               Location l = (Location) oob_stack.Pop ();
-
-               current_block = prev_block;
+               LocalVariableReference v = (LocalVariableReference) $9;
+               Location l = (Location) $6;
 
                if (v != null) {
                        Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
-                       foreach_block.AddStatement (f);
+                       current_block.AddStatement (f);
                }
 
-               $$ = foreach_block;
+               while (current_block.Implicit)
+                         current_block = current_block.Parent;
+               $$ = current_block;
+               current_block = current_block.Parent;
          }
        ;
 
@@ -3924,7 +4454,7 @@ continue_statement
 goto_statement
        : GOTO IDENTIFIER SEMICOLON 
          {
-               $$ = new Goto (current_block, (string) $2, lexer.Location);
+               $$ = new Goto ((string) $2, lexer.Location);
          }
        | GOTO CASE constant_expression SEMICOLON
          {
@@ -3970,6 +4500,11 @@ yield_statement
                        $$ = new Yield ((Expression) $3, lexer.Location); 
                }
          }
+       | IDENTIFIER RETURN SEMICOLON
+       {
+               Report.Error (1627, lexer.Location, "Expression expected after yield return");
+               $$ = null;
+       }
        | IDENTIFIER BREAK SEMICOLON
          {
                string s = (string) $1;
@@ -4085,7 +4620,6 @@ catch_clause
 
                                one.Add (new VariableDeclaration (id, null, loc));
 
-                               $1 = current_block;
                                current_block = new Block (current_block);
                                Block b = declare_local_variables (type, one, loc);
                                current_block = b;
@@ -4100,17 +4634,14 @@ catch_clause
                        type = (Expression) cc.Key;
                        id   = (string) cc.Value;
 
-                       if ($1 != null){
-                               //
-                               // FIXME: I can change this for an assignment.
-                               //
-                               while (current_block != (Block) $1)
+                       if (id != null){
+                               while (current_block.Implicit)
                                        current_block = current_block.Parent;
+                               current_block = current_block.Parent;
                        }
                }
 
-
-               $$ = new Catch (type, id , (Block) $4, ((Block) $4).loc);
+               $$ = new Catch (type, id, (Block) $4, ((Block) $4).loc);
        }
         ;
 
@@ -4145,7 +4676,7 @@ unsafe_statement
        {
                if (!RootContext.Unsafe){
                        Report.Error (227, lexer.Location, 
-                               "Unsafe code can only be used if --unsafe is used");
+                               "Unsafe code can only be used if -unsafe is used");
                }
        } block {
                $$ = new Unsafe ((Block) $3);
@@ -4155,7 +4686,7 @@ unsafe_statement
 fixed_statement
        : FIXED OPEN_PARENS 
          type fixed_pointer_declarators 
-         CLOSE_PARENS 
+         CLOSE_PARENS _mark_
          {
                ArrayList list = (ArrayList) $4;
                Expression type = (Expression) $3;
@@ -4169,26 +4700,24 @@ fixed_statement
                        Pair p = (Pair) list [i];
                        LocalInfo v;
 
-                       v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
+                       v = current_block.AddVariable (type, (string) p.First, l);
                        if (v == null)
                                continue;
 
-                       v.ReadOnly = true;
+                       v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
                        v.Pinned = true;
                        p.First = v;
                        list [i] = p;
                }
-
-               oob_stack.Push (l);
          }
          embedded_statement 
          {
-               Location l = (Location) oob_stack.Pop ();
+               Location l = (Location) $6;
 
-               Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
+               Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $8, l);
 
-               if (RootContext.WarningLevel >= 3){
-                       if ($7 == EmptyStatement.Value)
+               if (RootContext.WarningLevel >= 4){
+                       if ($8 == EmptyStatement.Value)
                                Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
                }
 
@@ -4240,13 +4769,11 @@ lock_statement
        ;
 
 using_statement
-       : USING OPEN_PARENS resource_acquisition CLOSE_PARENS 
+       : USING OPEN_PARENS resource_acquisition CLOSE_PARENS _mark_
          {
                Block assign_block = new Block (current_block);
                current_block = assign_block;
 
-               oob_stack.Push (lexer.Location);
-               
                if ($3 is DictionaryEntry){
                        DictionaryEntry de = (DictionaryEntry) $3;
                        Location l = lexer.Location;
@@ -4258,12 +4785,10 @@ using_statement
 
                        foreach (VariableDeclaration decl in var_declarators){
 
-                               LocalInfo vi    = current_block.AddVariable (
-                                       type, decl.identifier, 
-                                       current_local_parameters, decl.Location);
+                               LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location);
                                if (vi == null)
                                        continue;
-                               vi.ReadOnly = true;
+                               vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
 
                                Expression expr;
                                if (decl.expression_or_array_initializer is Expression){
@@ -4290,12 +4815,17 @@ using_statement
                                // Assign a = new Assign (var, expr, decl.Location);
                                // assign_block.AddStatement (new StatementExpression (a, lexer.Location));
                        }
-                       $3 = new DictionaryEntry (type, vars);
+
+                       // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
+                       // It can be referred to as $6 below.
+                       $$ = new DictionaryEntry (type, vars);
+                } else {
+                       $$ = $3;
                 }
          } 
          embedded_statement
          {
-               Using u = new Using ($3, (Statement) $6, (Location) oob_stack.Pop ());
+               Using u = new Using ($6, (Statement) $7, (Location) $5);
                current_block.AddStatement (u);
                while (current_block.Implicit)
                        current_block = current_block.Parent;
@@ -4309,6 +4839,11 @@ resource_acquisition
        | expression
        ;
 
+// Utility rule to save location information
+_mark_
+       : /* empty */
+       { $$ = lexer.Location; }
+
 %%
 
 // <summary>
@@ -4319,6 +4854,7 @@ public class VariableDeclaration {
        public object expression_or_array_initializer;
        public Location Location;
        public Attributes OptAttributes;
+       public string DocComment;
 
        public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs)
        {
@@ -4341,13 +4877,19 @@ public class InterfaceAccessorInfo {
         public readonly Accessor Get, Set;
 
         public InterfaceAccessorInfo (bool has_get, bool has_set,
-                                      Attributes get_attrs, Attributes set_attrs, Location get_loc, Location set_loc)
+                                      Attributes get_attrs, Attributes set_attrs, int get_mod, int set_mod, Location get_loc, Location set_loc)
         {
+               if (get_mod != 0)
+                       Report.Error (275, get_loc, "Accessibility modifiers can not be used on accessors in interfaces");
+               if (set_mod != 0)
+                       Report.Error (275, set_loc, "Accessibility modifiers can not be used on accessors in interfaces");
+                       
                if (has_get)
-                       Get = new Accessor (null, get_attrs, get_loc);
+                       Get = new Accessor (null, 0, get_attrs, get_loc);
                if (has_set)
-                       Set = new Accessor (null, set_attrs, set_loc);
+                       Set = new Accessor (null, 0, set_attrs, set_loc);
         }
+
 }
 
 
@@ -4420,6 +4962,23 @@ void Error_ExpectingTypeName (Location l, Expression expr)
        }
 }
 
+TypeContainer pop_current_class ()
+{
+       TypeContainer retval = current_class;
+
+       current_class = current_class.Parent;
+       current_container = current_container.Parent;
+       
+       if (current_class != current_container) {
+               if (!(current_class is ClassPart) ||
+                   ((ClassPart) current_class).PartialContainer != current_container)
+                       throw new InternalErrorException ();
+       } else if (current_container is ClassPart)
+               current_container = ((ClassPart) current_class).PartialContainer;
+
+       return retval;
+}
+
 // <summary>
 //   Given the @class_name name, it creates a fully qualified name
 //   based on the containing declaration space
@@ -4427,11 +4986,11 @@ void Error_ExpectingTypeName (Location l, Expression expr)
 MemberName
 MakeName (MemberName class_name)
 {
-       string ns = current_namespace.FullName;
+       Namespace ns = current_namespace.NS;
 
        if (current_container.Name == ""){
-               if (ns != "")
-                       return new MemberName (new MemberName (ns), class_name);
+               if (ns.Name != "")
+                       return new MemberName (ns.MemberName, class_name);
                else
                        return class_name;
        } else {
@@ -4466,7 +5025,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
 
        foreach (VariableDeclaration decl in variable_declarators){
 
-               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
+               if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
                        if (decl.expression_or_array_initializer != null){
                                if (inits == null)
                                        inits = new ArrayList (4);
@@ -4512,8 +5071,7 @@ Block declare_local_constants (Expression type, ArrayList declarators)
                implicit_block = current_block;
 
        foreach (VariableDeclaration decl in declarators){
-               implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
-                                                 current_local_parameters, decl.Location);
+               implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, decl.Location);
        }
        
        return implicit_block;
@@ -4592,11 +5150,6 @@ void syntax_error (Location l, string msg)
        Report.Error (1003, l, "Syntax error, " + msg);
 }
 
-void output (string s)
-{
-       Console.WriteLine (s);
-}
-
 void note (string s)
 {
        // Used to put annotations
@@ -4616,6 +5169,8 @@ public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList def
        this.name = file.Name;
        this.file = file;
        current_container = RootContext.Tree.Types;
+       // TODO: Make RootContext.Tree.Types a PartialContainer.
+       current_class = current_container;
        current_container.NamespaceEntry = current_namespace;
        oob_stack = new Stack ();
        switch_stack = new Stack ();
@@ -4626,21 +5181,23 @@ public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList def
 public void parse ()
 {
        try {
-               if (yacc_verbose_flag)
+               if (yacc_verbose_flag > 1)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else
                        yyparse (lexer);
                Tokenizer tokenizer = lexer as Tokenizer;
-               tokenizer.cleanup ();           
+               tokenizer.cleanup ();
        } catch (Exception e){
                //
                // Removed for production use, use parser verbose to get the output.
                //
                // Console.WriteLine (e);
                Report.Error (-25, lexer.Location, "Parsing error");
-               if (Driver.parser_verbose)
+               if (yacc_verbose_flag > 0)
                        Console.WriteLine (e);
        }
+
+       RootContext.Tree.Types.NamespaceEntry = null;
 }
 
 void CheckToken (int error, int yyToken, string msg)
@@ -4657,5 +5214,13 @@ void CheckIdentifierToken (int yyToken)
        CheckToken (1041, yyToken, "Identifier expected");
 }
 
+string ConsumeStoredComment ()
+{
+       string s = tmpComment;
+       tmpComment = null;
+       Lexer.doc_state = XmlCommentState.Allowed;
+       return s;
+}
+
 /* end end end */
 }