remove experimental code in #if false .. #endif
[mono.git] / mcs / mcs / cs-parser.jay
old mode 100755 (executable)
new mode 100644 (file)
index e08ef48..36e524f
@@ -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
@@ -81,8 +82,14 @@ 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;
                
@@ -284,7 +291,13 @@ compilation_unit
        
 opt_EOF
        : /* empty */
+       {
+               Lexer.check_incorrect_doc_comment ();
+       }
        | EOF
+       {
+               Lexer.check_incorrect_doc_comment ();
+       }
        ;
 
 outer_declarations
@@ -304,14 +317,23 @@ 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
        : USING IDENTIFIER ASSIGN 
          namespace_or_type_name SEMICOLON
          {
-               current_namespace.UsingAlias ((string) $2, (MemberName) $4, lexer.Location);
+               MemberName name = (MemberName) $4;
+               current_namespace.UsingAlias ((string) $2, name.GetTypeExpression (lexer.Location), lexer.Location);
          }
        | USING error {
                CheckIdentifierToken (yyToken);
@@ -321,7 +343,8 @@ using_alias_directive
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((string) $2, lexer.Location);
+               MemberName ns_name = (MemberName) $2;
+               current_namespace.Using (ns_name.GetTypeExpression (lexer.Location), lexer.Location);
           }
        ;
 
@@ -366,15 +389,15 @@ opt_comma
        ;
 
 namespace_name
-       : namespace_or_type_name {
-               MemberName name = (MemberName) $1;
-
-               $$ = name.GetName ();
-         }
+       : namespace_or_type_name
        ;
 
 namespace_body
        : OPEN_BRACE
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_using_directives
          opt_namespace_member_declarations
          CLOSE_BRACE
@@ -491,6 +514,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);
                }               
@@ -579,14 +609,18 @@ attribute
          }
          opt_attribute_arguments
          {
+                 Location loc = (Location) $2;
                MemberName mname = (MemberName) $1;
-               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);
+                                                 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);
          }
        ;
 
@@ -746,9 +780,16 @@ struct_declaration
                if ($7 != null)
                        current_class.Bases = (ArrayList) $7;
 
+               if (RootContext.Documentation != null)
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+
                current_class.Register ();
          }
          struct_body
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_semicolon
          {
                $$ = current_class;
@@ -762,7 +803,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
@@ -814,6 +860,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);
                }
          }
@@ -860,15 +910,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  
@@ -878,6 +951,28 @@ 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 
          {
@@ -927,6 +1022,8 @@ variable_initializer
 method_declaration
        : method_header {
                iterator_container = (IIteratorContainer) $1;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
          }
          method_body
          {
@@ -953,6 +1050,9 @@ method_declaration
 
                current_local_parameters = null;
                iterator_container = null;
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
@@ -989,6 +1089,9 @@ method_header
 
                current_local_parameters = (Parameters) $6;
 
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        | opt_attributes
@@ -1003,6 +1106,10 @@ method_header
                                            (Attributes) $1, lexer.Location);
 
                current_local_parameters = (Parameters) $6;
+
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        | opt_attributes
@@ -1020,6 +1127,10 @@ method_header
                                            lexer.Location);
 
                current_local_parameters = (Parameters) $7;
+
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        ;
@@ -1163,7 +1274,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;
@@ -1181,11 +1297,11 @@ property_declaration
          CLOSE_BRACE
          { 
                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;
 
                prop = new Property (current_class, (Expression) $3, (int) $2, false,
@@ -1196,6 +1312,10 @@ property_declaration
                current_container.AddProperty (prop);
                implicit_value_parameter_type = null;
                iterator_container = null;
+
+               if (RootContext.Documentation != null)
+                       prop.DocComment = ConsumeStoredComment ();
+
          }
        ;
 
@@ -1236,6 +1356,10 @@ get_accessor_declaration
                $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
                current_local_parameters = null;
                lexer.PropertyParsing = true;
+
+               if (RootContext.Documentation != null)
+                       if (Lexer.doc_state == XmlCommentState.Error)
+                               Lexer.doc_state = XmlCommentState.NotAllowed;
          }
        ;
 
@@ -1273,6 +1397,10 @@ set_accessor_declaration
                $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
                current_local_parameters = null;
                lexer.PropertyParsing = true;
+
+               if (RootContext.Documentation != null
+                       && Lexer.doc_state == XmlCommentState.Error)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
          }
        ;
 
@@ -1310,9 +1438,18 @@ interface_declaration
          {
                current_class.Bases = (ArrayList) $7;
 
+               if (RootContext.Documentation != null) {
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                current_class.Register ();
          }
          interface_body 
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_semicolon 
          {
                $$ = current_class;
@@ -1346,27 +1483,76 @@ interface_member_declaration
          { 
                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        
          { 
                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
          { 
                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");
+         } 
        ;
 
 opt_new
@@ -1387,6 +1573,8 @@ interface_method_declaration
 
                $$ = new Method (current_class, (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
@@ -1396,6 +1584,8 @@ interface_method_declaration
 
                $$ = new Method (current_class, TypeManager.system_void_expr, (int) $2,
                                 true, name, (Parameters) $6,  (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Method) $$).DocComment = Lexer.consume_doc_comment ();
          }
        ;
 
@@ -1414,6 +1604,8 @@ interface_property_declaration
                $$ = 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
@@ -1440,6 +1632,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);
@@ -1470,6 +1664,8 @@ interface_indexer_declaration
                                  new MemberName (TypeContainer.DefaultIndexerName),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
                                  info.Get, info.Set, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Indexer) $$).DocComment = ConsumeStoredComment ();
          }
        ;
 
@@ -1493,6 +1689,11 @@ operator_declaration
                        new Parameters (param_list, null, decl.location),
                        (ToplevelBlock) $5, (Attributes) $1, decl.location);
 
+               if (RootContext.Documentation != null) {
+                       op.DocComment = tmpComment;
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                if (SimpleIteratorContainer.Simple.Yields)
                        op.SetYields ();
 
@@ -1522,12 +1723,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);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);
 
-               $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+
+               $$ = new OperatorDeclaration (op, (Expression) $1, type, (string) $6,
                                              null, null, lexer.Location);
        }
        | type OPERATOR overloadable_operator
@@ -1536,18 +1743,26 @@ operator_declarator
                type IDENTIFIER 
          CLOSE_PARENS
         {
-              CheckBinaryOperator ((Operator.OpType) $3);
+               CheckBinaryOperator ((Operator.OpType) $3);
+
+               Parameter [] pars = new Parameter [2];
 
-              Parameter [] pars = new Parameter [2];
+               Expression typeL = (Expression) $5;
+               Expression typeR = (Expression) $8;
 
-              pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
-              pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
+              pars [0] = new Parameter (typeL, (string) $6, Parameter.Modifier.NONE, null);
+              pars [1] = new Parameter (typeR, (string) $9, Parameter.Modifier.NONE, null);
 
               current_local_parameters = new Parameters (pars, null, lexer.Location);
+
+               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
        ;
@@ -1589,6 +1804,11 @@ conversion_operator_declarator
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);  
                  
+               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);
          }
@@ -1600,6 +1820,11 @@ conversion_operator_declarator
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);  
                  
+               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);
          }
@@ -1624,6 +1849,9 @@ constructor_declaration
                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){
@@ -1657,22 +1885,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);
          }
        ;
 
@@ -1708,11 +1941,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.Basename){
                        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;
@@ -1734,8 +1974,10 @@ destructor_declaration
                        Method d = new Destructor (
                                current_class, TypeManager.system_void_expr, m, "Finalize", 
                                new Parameters (null, null, l), (Attributes) $1, l);
+                       if (RootContext.Documentation != null)
+                               d.DocComment = ConsumeStoredComment ();
                  
-                       d.Block = (ToplevelBlock) $7;
+                       d.Block = (ToplevelBlock) $8;
                        current_container.AddMethod (d);
                }
          }
@@ -1756,17 +1998,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
          {
@@ -1774,13 +2019,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;
 
@@ -1788,7 +2033,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;
                }
@@ -1800,6 +2049,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;
          }
        ;
 
@@ -1872,7 +2124,7 @@ remove_accessor_declaration
 
 indexer_declaration
        : opt_attributes opt_modifiers indexer_declarator 
-         OPEN_BRACE 
+         OPEN_BRACE _mark_
          {
                IndexerDeclaration decl = (IndexerDeclaration) $3;
 
@@ -1882,7 +2134,6 @@ indexer_declaration
                parsing_indexer  = true;
                
                indexer_parameters = decl.param_list;
-               oob_stack.Push (lexer.Location);
          }
           accessor_declarations 
          {
@@ -1893,10 +2144,10 @@ indexer_declaration
          { 
                // 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;
 
@@ -1910,6 +2161,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);
                
@@ -1929,6 +2182,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);
          }
@@ -1942,8 +2199,14 @@ 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;
                $$ = new IndexerDeclaration ((Expression) $1, name, pars);
+
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
          }
        ;
 
@@ -1951,7 +2214,10 @@ enum_declaration
        : opt_attributes
          opt_modifiers
          ENUM IDENTIFIER 
-         opt_enum_base
+         opt_enum_base {
+               if (RootContext.Documentation != null)
+                       enumTypeComment = Lexer.consume_doc_comment ();
+         }
          enum_body
          opt_semicolon
          { 
@@ -1961,10 +2227,14 @@ enum_declaration
                Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
                                   full_name, (Attributes) $1, enum_location);
                
-               foreach (VariableDeclaration ev in (ArrayList) $6) {
+               if (RootContext.Documentation != null)
+                       e.DocComment = enumTypeComment;
+
+               foreach (VariableDeclaration ev in (ArrayList) $7) {
                        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 ();
@@ -1980,9 +2250,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;
          }
        ;
 
@@ -2012,15 +2293,31 @@ 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;
          }
        ;
 
@@ -2036,6 +2333,11 @@ delegate_declaration
                Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
                                             (int) $2, name, (Parameters) $7, (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);
          }     
@@ -2052,6 +2354,11 @@ delegate_declaration
                        TypeManager.system_void_expr, (int) $2, name,
                        (Parameters) $7, (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);
          }
@@ -2314,6 +2621,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
@@ -2344,7 +2663,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);
          }
@@ -2615,24 +2941,26 @@ 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;
 
                // Force the next block to be created as a ToplevelBlock
                oob_stack.Push (current_block);
                oob_stack.Push (top_current_block);
-               oob_stack.Push (lexer.Location);
                current_block = null;
-         } block {
-               Location loc = (Location) oob_stack.Pop ();
+         } 
+         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  {
-                       ToplevelBlock anon_block = (ToplevelBlock) $4;
+                       ToplevelBlock anon_block = (ToplevelBlock) $5;
 
                        anon_block.Parent = current_block;
                        $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block, 
@@ -3055,9 +3383,18 @@ class_declaration
                        current_class.Bases = (ArrayList) $7;
                }
 
+               if (RootContext.Documentation != null) {
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                current_class.Register ();
          }
-         class_body 
+         class_body
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_semicolon 
          {
                $$ = current_class;
@@ -3395,52 +3732,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 ();
          }
        ;
@@ -3529,16 +3851,12 @@ iteration_statement
        ;
 
 while_statement
-       : WHILE OPEN_PARENS 
-       {
-               oob_stack.Push (lexer.Location);
-       }
-       boolean_expression CLOSE_PARENS embedded_statement
+       : WHILE OPEN_PARENS _mark_ 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");
                }
@@ -3547,12 +3865,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);
          }
@@ -3560,7 +3875,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;
@@ -3601,20 +3916,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");
                }
 
@@ -3674,16 +3992,12 @@ foreach_statement
                Report.Error (230, lexer.Location, "Type and identifier are both required in a foreach statement");
                $$ = null;
        }
-       | FOREACH OPEN_PARENS type IDENTIFIER IN 
-         {
-               oob_stack.Push (lexer.Location);
-         }
+       | 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;
 
@@ -3692,28 +4006,28 @@ foreach_statement
                        vi.ReadOnly = true;
 
                        // 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;
          }
        ;
 
@@ -3904,7 +4218,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;
@@ -3919,17 +4232,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);
        }
         ;
 
@@ -3974,7 +4284,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;
@@ -3997,17 +4307,15 @@ fixed_statement
                        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");
                }
 
@@ -4059,13 +4367,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;
@@ -4109,12 +4415,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;
@@ -4128,6 +4439,11 @@ resource_acquisition
        | expression
        ;
 
+// Utility rule to save location information
+_mark_
+       : /* empty */
+       { $$ = lexer.Location; }
+
 %%
 
 // <summary>
@@ -4138,6 +4454,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)
        {
@@ -4482,5 +4799,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 */
 }