2008-06-25 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / cs-parser.jay
index 5450088db1e334780ff8f5ca01218582716abd37..a48ed260b13b0aec6577dfa2c7418700c3d0eb02 100644 (file)
@@ -53,6 +53,9 @@ namespace Mono.CSharp
                ///   This is used by the unary_expression code to resolve
                ///   a name against a parameter.  
                /// </summary>
+               
+               // FIXME: This is very ugly and it's very hard to reset it correctly
+               // on all places, especially when some parameters are autogenerated.
                Parameters current_local_parameters;
 
                /// <summary>
@@ -60,14 +63,14 @@ namespace Mono.CSharp
                ///   value parameter that is passed to the "set" and "get"accesor
                ///   methods (properties and indexers).
                /// </summary>
-               Expression implicit_value_parameter_type;
+               FullNamedExpression implicit_value_parameter_type;
                Parameters indexer_parameters;
 
                /// <summary>
                ///   Hack to help create non-typed array initializer
                /// </summary>
-               public static Expression current_array_type;
-               Expression pushed_current_array_type;
+               public static FullNamedExpression current_array_type;
+               FullNamedExpression pushed_current_array_type;
 
                /// <summary>
                ///   Used to determine if we are parsing the get/set pair
@@ -89,13 +92,10 @@ namespace Mono.CSharp
 
                static public int yacc_verbose_flag;
 
-               // Name of the file we are parsing
-               public string name;
-
                ///
                /// The current file.
                ///
-               SourceFile file;
+               CompilationUnit file;
 
                ///
                /// Temporary Xml documentation cache.
@@ -368,7 +368,7 @@ extern_alias_directive
                        Report.FeatureIsNotAvailable (lt.Location, "external alias");
                } else {
                        lt = (LocatedToken) $3; 
-                       current_namespace.UsingExternalAlias (lt.Value, lt.Location);
+                       current_namespace.AddUsingExternalAlias (lt.Value, lt.Location);
                }
          }
        ;
@@ -396,7 +396,7 @@ using_alias_directive
          namespace_or_type_name SEMICOLON
          {
                LocatedToken lt = (LocatedToken) $2;
-               current_namespace.UsingAlias (lt.Value, (MemberName) $4, (Location) $1);
+               current_namespace.AddUsingAlias (lt.Value, (MemberName) $4, (Location) $1);
          }
        | USING error {
                CheckIdentifierToken (yyToken, GetLocation ($2));
@@ -406,8 +406,8 @@ using_alias_directive
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((MemberName) $2, (Location) $1);
-          }
+               current_namespace.AddUsing ((MemberName) $2, (Location) $1);
+         }
        ;
 
 //
@@ -933,7 +933,7 @@ constant_declaration
                        }
 
                        Const c = new Const (
-                               current_class, (Expression) $4, (string) constant.identifier, 
+                               current_class, (FullNamedExpression) $4, (string) constant.identifier, 
                                (Expression) constant.expression_or_array_initializer, modflags, 
                                (Attributes) $1, l);
 
@@ -983,7 +983,7 @@ field_declaration
          variable_declarators
          SEMICOLON
          { 
-               Expression type = (Expression) $3;
+               FullNamedExpression type = (FullNamedExpression) $3;
                int mod = (int) $2;
 
                current_array_type = null;
@@ -1009,7 +1009,7 @@ field_declaration
          fixed_variable_declarators
          SEMICOLON
          { 
-                       Expression type = (Expression) $4;
+                       FullNamedExpression type = (FullNamedExpression) $4;
                        int mod = (int) $2;
 
                        current_array_type = null;
@@ -1207,12 +1207,12 @@ method_header
                GenericMethod generic = null;
                if (name.TypeArguments != null) {
                        generic = new GenericMethod (current_namespace, current_class, name,
-                                                    (Expression) $3, current_local_parameters);
+                                                    (FullNamedExpression) $3, current_local_parameters);
 
                        generic.SetParameterInfo ((ArrayList) $10);
                }
 
-               method = new Method (current_class, generic, (Expression) $3, (int) $2, false,
+               method = new Method (current_class, generic, (FullNamedExpression) $3, (int) $2, false,
                                     name, current_local_parameters, (Attributes) $1);
 
                anonymous_host = method;
@@ -1443,7 +1443,7 @@ fixed_parameters
                ArrayList pars = (ArrayList) $1;
                Parameter p = (Parameter)$3;
                if (p != null) {
-                       if ((p.modFlags & Parameter.Modifier.This) != 0)
+                       if (p.HasExtensionMethodModifier)
                                Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter");
                        pars.Add (p);
                }
@@ -1458,7 +1458,7 @@ fixed_parameter
          IDENTIFIER
          {
                LocatedToken lt = (LocatedToken) $4;
-               $$ = new Parameter ((Expression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
+               $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
          }
        | opt_attributes
          opt_parameter_modifier
@@ -1560,7 +1560,7 @@ parameter_array
        : opt_attributes params_modifier type IDENTIFIER
          { 
                LocatedToken lt = (LocatedToken) $4;
-               $$ = new ParamsParameter ((Expression) $3, lt.Value, (Attributes) $1, lt.Location);
+               $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);
          }
        | opt_attributes params_modifier type error {
                CheckIdentifierToken (yyToken, GetLocation ($4));
@@ -1608,7 +1608,7 @@ property_declaration
          }
          OPEN_BRACE 
          {
-               implicit_value_parameter_type = (Expression) $3;
+               implicit_value_parameter_type = (FullNamedExpression) $3;
 
                lexer.PropertyParsing = true;
          }
@@ -1632,7 +1632,7 @@ property_declaration
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "a property can't have type arguments");
 
-               prop = new Property (current_class, (Expression) $3, (int) $2, false,
+               prop = new Property (current_class, (FullNamedExpression) $3, (int) $2, false,
                                     name, (Attributes) $1, get_block, set_block, accessors.declared_in_reverse, current_block);
 
                current_container.AddProperty (prop);
@@ -1977,12 +1977,12 @@ interface_method_declaration
                GenericMethod generic = null;
                if (name.TypeArguments != null) {
                        generic = new GenericMethod (current_namespace, current_class, name,
-                                                    (Expression) $3, (Parameters) $6);
+                                                    (FullNamedExpression) $3, (Parameters) $6);
 
                        generic.SetParameterInfo ((ArrayList) $9);
                }
 
-               $$ = new Method (current_class, generic, (Expression) $3, (int) $2, true, name,
+               $$ = new Method (current_class, generic, (FullNamedExpression) $3, (int) $2, true, name,
                                 (Parameters) $6, (Attributes) $1);
                if (RootContext.Documentation != null)
                        ((Method) $$).DocComment = Lexer.consume_doc_comment ();
@@ -2028,7 +2028,7 @@ interface_property_declaration
          OPEN_BRACE 
          {
                lexer.PropertyParsing = true;
-               implicit_value_parameter_type = (Expression)$3;
+               implicit_value_parameter_type = (FullNamedExpression)$3;
          }
          accessor_declarations 
          {
@@ -2048,7 +2048,7 @@ interface_property_declaration
 
                Property p = null;
                if ($7 == null) {
-                       p = new Property (current_class, (Expression) $3, (int) $2, true,
+                       p = new Property (current_class, (FullNamedExpression) $3, (int) $2, true,
                                   name, (Attributes) $1,
                                   null, null, false);
 
@@ -2057,7 +2057,7 @@ interface_property_declaration
                }
 
                Accessors accessor = (Accessors) $7;
-               p = new Property (current_class, (Expression) $3, (int) $2, true,
+               p = new Property (current_class, (FullNamedExpression) $3, (int) $2, true,
                                   name, (Attributes) $1,
                                   accessor.get_or_add, accessor.set_or_remove, accessor.declared_in_reverse);
 
@@ -2091,7 +2091,7 @@ interface_event_declaration
        : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
          {
                LocatedToken lt = (LocatedToken) $5;
-               $$ = new EventField (current_class, (Expression) $4, (int) $2, true,
+               $$ = new EventField (current_class, (FullNamedExpression) $4, (int) $2, true,
                                     new MemberName (lt.Value, lt.Location),
                                     (Attributes) $1);
                if (RootContext.Documentation != null)
@@ -2108,7 +2108,7 @@ interface_event_declaration
          }
        | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE
          {
-               implicit_value_parameter_type = (Expression) $4;
+               implicit_value_parameter_type = (FullNamedExpression) $4;
                lexer.EventParsing = true;
          }
          event_accessor_declarations
@@ -2128,7 +2128,7 @@ interface_indexer_declaration
          OPEN_BRACE
          {
                lexer.PropertyParsing = true;
-               implicit_value_parameter_type = (Expression)$3;
+               implicit_value_parameter_type = (FullNamedExpression)$3;
          }
          accessor_declarations 
          { 
@@ -2140,7 +2140,7 @@ interface_indexer_declaration
          {
                Indexer i = null;
                if ($10 == null) {
-                       i = new Indexer (current_class, (Expression) $3,
+                       i = new Indexer (current_class, (FullNamedExpression) $3,
                                  new MemberName (TypeContainer.DefaultIndexerName, (Location) $4),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
                                  null, null, false);
@@ -2150,7 +2150,7 @@ interface_indexer_declaration
                }
 
                Accessors accessors = (Accessors) $10;
-               i = new Indexer (current_class, (Expression) $3,
+               i = new Indexer (current_class, (FullNamedExpression) $3,
                                  new MemberName (TypeContainer.DefaultIndexerName, (Location) $4),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
                                   accessors.get_or_add, accessors.set_or_remove, accessors.declared_in_reverse);
@@ -2252,7 +2252,7 @@ operator_declarator
                        Lexer.doc_state = XmlCommentState.NotAllowed;
                }
 
-               $$ = new OperatorDeclaration (op, (Expression) $1, loc);
+               $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc);
          }
        | conversion_operator_declarator
        ;
@@ -2302,7 +2302,7 @@ conversion_operator_declarator
                        Lexer.doc_state = XmlCommentState.NotAllowed;
                }
 
-               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, loc);
+               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc);
          }
        | EXPLICIT OPERATOR type open_parens
          {
@@ -2320,7 +2320,7 @@ conversion_operator_declarator
                        Lexer.doc_state = XmlCommentState.NotAllowed;
                }
 
-               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, loc);
+               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc);
          }
        | IMPLICIT error 
          {
@@ -2477,7 +2477,7 @@ event_declaration
                                var.Location);
 
                        EventField e = new EventField (
-                               current_class, (Expression) $4, (int) $2, false, name,
+                               current_class, (FullNamedExpression) $4, (int) $2, false, name,
                                (Attributes) $1);
 
                        e.Initializer = var.expression_or_array_initializer;
@@ -2495,7 +2495,7 @@ event_declaration
          EVENT type namespace_or_type_name
          OPEN_BRACE
          {
-               implicit_value_parameter_type = (Expression) $4;  
+               implicit_value_parameter_type = (FullNamedExpression) $4;  
                lexer.EventParsing = true;
          }
          event_accessor_declarations
@@ -2521,7 +2521,7 @@ event_declaration
                                $$ = null;
                        else {
                                Event e = new EventProperty (
-                                       current_class, (Expression) $4, (int) $2, false, name,
+                                       current_class, (FullNamedExpression) $4, (int) $2, false, name,
                                        (Attributes) $1, accessors.get_or_add, accessors.set_or_remove);
                                if (RootContext.Documentation != null) {
                                        e.DocComment = Lexer.consume_doc_comment ();
@@ -2616,10 +2616,11 @@ remove_accessor_declaration
                current_local_parameters = new Parameters (args);  
                lexer.EventParsing = false;
          }
-          block
+         block
          {
                $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2);
                lexer.EventParsing = true;
+               current_local_parameters = null;
          }
        | opt_attributes REMOVE error {
                Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
@@ -2698,7 +2699,7 @@ indexer_declarator
                        Lexer.doc_state = XmlCommentState.Allowed;
                }
 
-               $$ = new IndexerDeclaration ((Expression) $1, null, pars, (Location) $2);
+               $$ = new IndexerDeclaration ((FullNamedExpression) $1, null, pars, (Location) $2);
          }
        | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
          {
@@ -2708,7 +2709,7 @@ indexer_declarator
                }
 
                MemberName name = (MemberName) $2;
-               $$ = new IndexerDeclaration ((Expression) $1, name, pars, (Location) $4);
+               $$ = new IndexerDeclaration ((FullNamedExpression) $1, name, pars, (Location) $4);
 
                if (RootContext.Documentation != null) {
                        tmpComment = Lexer.consume_doc_comment ();
@@ -2732,7 +2733,7 @@ enum_declaration
                Location enum_location = lt.Location;
 
                MemberName name = MakeName (new MemberName (lt.Value, enum_location));
-               Enum e = new Enum (current_namespace, current_class, (Expression) $5, (int) $2,
+               Enum e = new Enum (current_namespace, current_class, (FullNamedExpression) $5, (int) $2,
                                   name, (Attributes) $1);
                
                if (RootContext.Documentation != null)
@@ -2845,7 +2846,7 @@ delegate_declaration
                MemberName name = MakeName ((MemberName) $5);
                Parameters p = (Parameters) $7;
 
-               Delegate del = new Delegate (current_namespace, current_class, (Expression) $4,
+               Delegate del = new Delegate (current_namespace, current_class, (FullNamedExpression) $4,
                                             (int) $2, name, p, (Attributes) $1);
 
                if (RootContext.Documentation != null) {
@@ -2896,7 +2897,10 @@ namespace_or_type_name
        | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list {
                LocatedToken lt1 = (LocatedToken) $1;
                LocatedToken lt2 = (LocatedToken) $3;
-               $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $4, lt2.Location);
+               if (RootContext.Version == LanguageVersion.ISO_1)
+                       Report.FeatureIsNotAvailable (lt1.Location, "namespace alias qualifier");
+               
+               $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $4, lt1.Location);
          }
        | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list {
                LocatedToken lt = (LocatedToken) $3;
@@ -3000,7 +3004,7 @@ type
                if ((bool) $2) {
                        $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location);
                } else {
-                       if (RootContext.Version > LanguageVersion.ISO_2 && name.Name == "var")
+                       if (RootContext.Version > LanguageVersion.ISO_2 && name.Left == null && name.Name == "var")
                                $$ = new VarExpr (name.Location);
                        else
                                $$ = name.GetTypeExpression ();
@@ -3009,7 +3013,7 @@ type
        | builtin_types opt_nullable
          {
                if ((bool) $2)
-                       $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
+                       $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
          }
        | array_type
        | pointer_type
@@ -3023,7 +3027,7 @@ pointer_type
                // can't perform checks during this phase - we do it during
                // semantic analysis.
                //
-               $$ = new ComposedCast ((Expression) $1, "*", Lexer.Location);
+               $$ = new ComposedCast ((FullNamedExpression) $1, "*", Lexer.Location);
          }
        | VOID STAR
          {
@@ -3035,29 +3039,21 @@ non_expression_type
        : builtin_types opt_nullable
          {
                if ((bool) $2)
-                       $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
+                       $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
          }
        | non_expression_type rank_specifier
          {
                Location loc = GetLocation ($1);
                if (loc.IsNull)
                        loc = lexer.Location;
-               $$ = new ComposedCast ((Expression) $1, (string) $2, loc);
+               $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, loc);
          }
        | non_expression_type STAR
          {
                Location loc = GetLocation ($1);
                if (loc.IsNull)
                        loc = lexer.Location;
-               $$ = new ComposedCast ((Expression) $1, "*", loc);
-         }
-       | expression rank_specifiers 
-         {
-               $$ = new ComposedCast ((Expression) $1, (string) $2);
-         }
-       | expression STAR 
-         {
-               $$ = new ComposedCast ((Expression) $1, "*");
+               $$ = new ComposedCast ((FullNamedExpression) $1, "*", loc);
          }
        
        //
@@ -3066,27 +3062,38 @@ non_expression_type
        //
        | multiplicative_expression STAR 
          {
-               $$ = new ComposedCast ((Expression) $1, "*");
+               FullNamedExpression e = $1 as FullNamedExpression;
+               if (e != null)
+                       $$ = new ComposedCast (e, "*");
+               else
+                       Error_TypeExpected (GetLocation ($1));
          }
        ;
 
 type_list
-       : type
+       : base_type_name
          {
-               ArrayList types = new ArrayList (4);
-
+               ArrayList types = new ArrayList (2);
                types.Add ($1);
                $$ = types;
          }
-       | type_list COMMA type
+       | type_list COMMA base_type_name
          {
                ArrayList types = (ArrayList) $1;
-
                types.Add ($3);
                $$ = types;
          }
        ;
 
+base_type_name
+       : type
+         {
+               if ($1 is ComposedCast)
+                       Report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
+               $$ = $1;
+         }
+       ;
+       
 /*
  * replaces all the productions for isolating the various
  * simple types, but we need this to reuse it easily in local_variable_type
@@ -3121,7 +3128,7 @@ array_type
                if ((bool) $3)
                        rank_specifiers += "?";
 
-               $$ = current_array_type = new ComposedCast ((Expression) $1, rank_specifiers);
+               $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank_specifiers);
          }
        ;
 
@@ -3138,14 +3145,14 @@ primary_expression
                MemberName mn = (MemberName) $1;
                $$ = mn.GetTypeExpression ();
          }
-       | IDENTIFIER DOUBLE_COLON IDENTIFIER
+       | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list
          {
                LocatedToken lt1 = (LocatedToken) $1;
                LocatedToken lt2 = (LocatedToken) $3;
                if (RootContext.Version == LanguageVersion.ISO_1)
                        Report.FeatureIsNotAvailable (lt1.Location, "namespace alias qualifier");
 
-               $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, lt2.Location);
+               $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $4, lt1.Location);
          }
        | parenthesized_expression
        | default_value_expression
@@ -3430,18 +3437,19 @@ element_access
                  
                Expression expr = (Expression) $1;  
                if (expr is ComposedCast){
-                       $$ = new ComposedCast (expr, (string) $2);
-               } else if (!(expr is SimpleName || expr is MemberAccess || expr is ConstructedType || expr is QualifiedAliasMember)){
-                       Error_ExpectingTypeName (expr);
-                       $$ = TypeManager.system_object_expr;
-               } else {
+                       $$ = new ComposedCast ((ComposedCast)expr, (string) $2);
+               } else if (expr is ATypeNameExpression){
                        //
                        // So we extract the string corresponding to the SimpleName
                        // or MemberAccess
                        // 
-                       $$ = new ComposedCast (expr, (string) $2);
+                       $$ = new ComposedCast ((ATypeNameExpression)expr, (string) $2);
+               } else {
+                       Error_ExpectingTypeName (expr);
+                       $$ = TypeManager.system_object_expr;
                }
-               current_array_type = (Expression)$$;
+               
+               current_array_type = (FullNamedExpression)$$;
          }
        ;
 
@@ -3531,11 +3539,11 @@ array_creation_expression
          opt_rank_specifier
          opt_array_initializer
          {
-               $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1);
+               $$ = new ArrayCreation ((FullNamedExpression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1);
          }
        | NEW type rank_specifiers array_initializer
          {
-               $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, (Location) $1);
+               $$ = new ArrayCreation ((FullNamedExpression) $2, (string) $3, (ArrayList) $4, (Location) $1);
          }
        | NEW rank_specifiers array_initializer
          {
@@ -3554,7 +3562,7 @@ array_creation_expression
        ;
 
 anonymous_type_expression
-       : NEW OPEN_BRACE anonymous_type_parameters CLOSE_BRACE
+       : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
          {
                if (RootContext.Version <= LanguageVersion.ISO_2)
                        Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
@@ -3563,9 +3571,18 @@ anonymous_type_expression
          }
        ;
 
-anonymous_type_parameters
+anonymous_type_parameters_opt_comma
+       : anonymous_type_parameters_opt
+       | anonymous_type_parameters COMMA
+       ;
+
+anonymous_type_parameters_opt
        : { $$ = null; }
-       | anonymous_type_parameter
+       | anonymous_type_parameters
+       ;
+
+anonymous_type_parameters
+       : anonymous_type_parameter
          {
                ArrayList a = new ArrayList (4);
                a.Add ($1);
@@ -3594,7 +3611,7 @@ anonymous_type_parameter
        | member_access
          {
                MemberAccess ma = (MemberAccess) $1;
-               $$ = new AnonymousTypeParameter (ma, ma.Identifier, ma.Location);
+               $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
          }
        | error
          {
@@ -3745,7 +3762,7 @@ typeof_type_expression
 unbound_type_name
        : IDENTIFIER GENERIC_DIMENSION
          {
-               if (RootContext.Version < LanguageVersion.ISO_1)
+               if (RootContext.Version < LanguageVersion.ISO_2)
                        Report.FeatureIsNotAvailable (lexer.Location, "generics");
          
                LocatedToken lt = (LocatedToken) $1;
@@ -3760,6 +3777,9 @@ unbound_type_name
                lt = (LocatedToken) $3;
                TypeArguments ta = new TypeArguments ((int)$4, lt.Location);
                
+               if (RootContext.Version == LanguageVersion.ISO_1)
+                       Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
+               
                $$ = new MemberName (left, lt.Value, ta, lt.Location);
          }
        | unbound_type_name DOT IDENTIFIER GENERIC_DIMENSION
@@ -3805,7 +3825,7 @@ pointer_member_access
                Expression deref;
                LocatedToken lt = (LocatedToken) $3;
 
-               deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lt.Location);
+               deref = new Indirection ((Expression) $1, lt.Location);
                $$ = new MemberAccess (deref, lt.Value);
          }
        ;
@@ -3911,7 +3931,7 @@ prefixed_unary_expression
          }
        | STAR prefixed_unary_expression
          {
-               $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, (Location) $1);
+               $$ = new Indirection ((Expression) $2, (Location) $1);
          }
        | BITWISE_AND prefixed_unary_expression
          {
@@ -4093,12 +4113,15 @@ conditional_expression
          }
        | conditional_or_expression OP_COALESCING expression
          {
+               if (RootContext.Version < LanguageVersion.ISO_2)
+                       Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
+                       
                $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, 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);
+               $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
                lexer.PutbackCloseParens ();
          }
        ;
@@ -4106,7 +4129,7 @@ conditional_expression
 assignment_expression
        : prefixed_unary_expression ASSIGN expression
          {
-               $$ = new Assign ((Expression) $1, (Expression) $3);
+               $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
          }
        | prefixed_unary_expression OP_MULT_ASSIGN expression
          {
@@ -4186,13 +4209,13 @@ lambda_parameter
          {
                LocatedToken lt = (LocatedToken) $3;
 
-               $$ = new Parameter ((Expression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
+               $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
          }
        | type IDENTIFIER
          {
                LocatedToken lt = (LocatedToken) $2;
 
-               $$ = new Parameter ((Expression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
+               $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
          }
        | IDENTIFIER
          {
@@ -4577,25 +4600,28 @@ local_variable_type
                // Foo.Bar.Blah i;
                // SimpleName is when you have
                // Blah i;
-                 
-               Expression expr = (Expression) $1;
-               SimpleName sn = expr as SimpleName;
-               if (!(sn != null || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType || expr is QualifiedAliasMember)) {
-                       Error_ExpectingTypeName (expr);
-                       $$ = null;
-               } else {
+               
+               Expression expr = (Expression) $1;  
+               if (expr is ComposedCast){
+                       $$ = new ComposedCast ((ComposedCast)expr, (string) $2);
+               } else if (expr is ATypeNameExpression){
                        //
                        // So we extract the string corresponding to the SimpleName
                        // or MemberAccess
-                       // 
-
+                       //
+                       
                        if ((string) $2 == "") {
+                               SimpleName sn = expr as SimpleName;
                                if (sn != null && RootContext.Version > LanguageVersion.ISO_2 && sn.Name == "var")
                                        $$ = new VarExpr (sn.Location);
                                else
                                        $$ = $1;
-                       } else
-                               $$ = new ComposedCast ((Expression) $1, (string) $2);
+                       } else {
+                               $$ = new ComposedCast ((ATypeNameExpression)expr, (string) $2);
+                       }
+               } else {
+                       Error_ExpectingTypeName (expr);
+                       $$ = TypeManager.system_object_expr;
                }
          }
        | builtin_types opt_rank_specifier_or_nullable
@@ -4603,25 +4629,25 @@ local_variable_type
                if ((string) $2 == "")
                        $$ = $1;
                else
-                       $$ = current_array_type = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+                       $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location);
          }
         ;
 
 local_variable_pointer_type
        : primary_expression STAR
          {
-               Expression expr = (Expression) $1;  
-
-               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType || expr is QualifiedAliasMember)) {
-                       Error_ExpectingTypeName (expr);
+               ATypeNameExpression expr = $1 as ATypeNameExpression;
 
-                       $$ = null;
-               } else 
-                       $$ = new ComposedCast ((Expression) $1, "*");
+               if (expr != null) {
+                       $$ = new ComposedCast (expr, "*");
+               } else {
+                       Error_ExpectingTypeName ((Expression)$1);
+                       $$ = expr;
+               }
          }
         | builtin_types STAR
          {
-               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+               $$ = new ComposedCast ((FullNamedExpression) $1, "*", lexer.Location);
          }
         | VOID STAR
          {
@@ -4629,7 +4655,7 @@ local_variable_pointer_type
          }
        | local_variable_pointer_type STAR
           {
-               $$ = new ComposedCast ((Expression) $1, "*");
+               $$ = new ComposedCast ((FullNamedExpression) $1, "*");
          }
         ;
 
@@ -4653,7 +4679,7 @@ local_variable_declaration
                        if ((string) $2 == "")
                                t = (Expression) $1;
                        else
-                               t = new ComposedCast ((Expression) $1, (string) $2);
+                               t = new ComposedCast ((FullNamedExpression) $1, (string) $2);
                        $$ = new DictionaryEntry (t, $3);
                } else 
                        $$ = null;
@@ -4870,7 +4896,7 @@ for_statement
                                var = new LocalVariableReference (assign_block, decl.identifier, l);
 
                                if (expr != null) {
-                                       Assign a = new Assign (var, expr, decl.Location);
+                                       Assign a = new SimpleAssign (var, expr, decl.Location);
                                        
                                        assign_block.AddStatement (new StatementExpression (a));
                                }
@@ -5088,43 +5114,17 @@ opt_expression
        ;
 
 try_statement
-       : TRY block catch_clauses 
+       : TRY block catch_clauses
          {
-               Catch g = null;
-               
-               ArrayList c = (ArrayList)$3;
-               for (int i = 0; i < c.Count; ++i) {
-                       Catch cc = (Catch) c [i];
-                       if (cc.IsGeneral) {
-                               if (i != c.Count - 1)
-                                       Report.Error (1017, cc.loc, "Try statement already has an empty catch block");
-                               g = cc;
-                               c.RemoveAt (i);
-                               i--;
-                       }
-               }
-
-               // Now s contains the list of specific catch clauses
-               // and g contains the general one.
-               
-               $$ = new Try ((Block) $2, c, g, null, ((Block) $2).loc);
+               $$ = new TryCatch ((Block) $2, (ArrayList) $3, (Location) $1, false);
          }
-       | TRY block opt_catch_clauses FINALLY block
+       | TRY block FINALLY block
          {
-               Catch g = null;
-               ArrayList s = new ArrayList (4);
-               ArrayList catch_list = (ArrayList) $3;
-
-               if (catch_list != null){
-                       foreach (Catch cc in catch_list) {
-                               if (cc.IsGeneral)
-                                       g = cc;
-                               else
-                                       s.Add (cc);
-                       }
-               }
-
-               $$ = new Try ((Block) $2, s, g, (Block) $5, ((Block) $2).loc);
+               $$ = new TryFinally ((Statement) $2, (Block) $4, (Location) $1);
+         }
+       | TRY block catch_clauses FINALLY block
+         {
+               $$ = new TryFinally (new TryCatch ((Block) $2, (ArrayList) $3, (Location) $1, true), (Block) $5, (Location) $1);
          }
        | TRY block error 
          {
@@ -5133,11 +5133,6 @@ try_statement
          }
        ;
 
-opt_catch_clauses
-       : /* empty */  { $$ = null; }
-        | catch_clauses
-       ;
-
 catch_clauses
        : catch_clause 
          {
@@ -5201,16 +5196,19 @@ catch_clause
 
 opt_catch_args
        : /* empty */ { $$ = null; }
-        | catch_args
+       | catch_args
        ;         
 
 catch_args 
-        : open_parens type opt_identifier CLOSE_PARENS 
-          {
+       : OPEN_PARENS type opt_identifier CLOSE_PARENS 
+         {
                $$ = new DictionaryEntry ($2, $3);
          }
-        ;
-
+       | OPEN_PARENS CLOSE_PARENS 
+         {
+               Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected");
+         }
+       ;
 
 checked_statement
        : CHECKED block
@@ -5315,66 +5313,72 @@ lock_statement
        ;
 
 using_statement
-       : USING open_parens resource_acquisition CLOSE_PARENS
+       : USING open_parens local_variable_declaration CLOSE_PARENS
          {
                start_block (lexer.Location);
                Block assign_block = current_block;
 
-               if ($3 is DictionaryEntry){
-                       DictionaryEntry de = (DictionaryEntry) $3;
-                       Location l = (Location) $1;
-
-                       Expression type = (Expression) de.Key;
-                       ArrayList var_declarators = (ArrayList) de.Value;
+               DictionaryEntry de = (DictionaryEntry) $3;
+               Location l = (Location) $1;
 
-                       ArrayList vars = new ArrayList (4);
+               Expression type = (Expression) de.Key;
+               ArrayList var_declarators = (ArrayList) de.Value;
 
-                       foreach (VariableDeclaration decl in var_declarators){
+               Stack vars = new Stack ();
 
-                               LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location);
-                               if (vi == null)
-                                       continue;
-                               vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
+               foreach (VariableDeclaration decl in var_declarators) {
+                       LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location);
+                       if (vi == null)
+                               continue;
+                       vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
 
-                               Expression expr = decl.expression_or_array_initializer;
-                               if (expr == null) {
-                                       Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
-                               }
+                       Expression expr = decl.expression_or_array_initializer;
+                       if (expr == null) {
+                               Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
+                               continue;
+                       }
+                       LocalVariableReference var;
 
-                               LocalVariableReference var;
+                       // Get a writable reference to this read-only variable.
+                       var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
 
-                               // Get a writable reference to this read-only variable.
-                               var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
+                       // This is so that it is not a warning on using variables
+                       vi.Used = true;
 
-                               // This is so that it is not a warning on using variables
-                               vi.Used = true;
+                       vars.Push (new DictionaryEntry (var, expr));
 
-                               vars.Add (new DictionaryEntry (var, expr));                             
+                       // Assign a = new SimpleAssign (var, expr, decl.Location);
+                       // assign_block.AddStatement (new StatementExpression (a));
+               }
 
-                               // Assign a = new Assign (var, expr, decl.Location);
-                               // assign_block.AddStatement (new StatementExpression (a));
-                       }
+               // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
+               // It can be referred to as $5 below.
+               $$ = vars;
+         }
+         embedded_statement
+         {
+               Statement stmt = (Statement) $6;
+               Stack vars = (Stack) $5;
+               Location l = (Location) $1;
 
-                       // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
-                       // It can be referred to as $5 below.
-                       $$ = new DictionaryEntry (type, vars);
-                } else {
-                       $$ = $3;
-                }
-         } 
+               while (vars.Count > 0) {
+                         DictionaryEntry de = (DictionaryEntry) vars.Pop ();
+                         stmt = new Using ((Expression) de.Key, (Expression) de.Value, stmt, l);
+               }
+               current_block.AddStatement (stmt);
+               $$ = end_block (lexer.Location);
+         }
+       | USING open_parens expression CLOSE_PARENS
+         {
+               start_block (lexer.Location);
+         }
          embedded_statement
          {
-               Using u = new Using ($5, (Statement) $6, (Location) $1);
-               current_block.AddStatement (u);
+               current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, (Location) $1));
                $$ = end_block (lexer.Location);
          }
        ; 
 
-resource_acquisition
-       : local_variable_declaration
-       | expression
-       ;
-
 
 // LINQ
 
@@ -5664,12 +5668,12 @@ public class VariableDeclaration {
 //   A class used to hold info about an indexer declarator
 // </summary>
 public class IndexerDeclaration {
-       public Expression type;
+       public FullNamedExpression type;
        public MemberName interface_type;
        public Parameters param_list;
        public Location location;
 
-       public IndexerDeclaration (Expression type, MemberName interface_type,
+       public IndexerDeclaration (FullNamedExpression type, MemberName interface_type,
                                   Parameters param_list, Location loc)
        {
                this.type = type;
@@ -5686,11 +5690,9 @@ public class SimpleAnonymousHost : IAnonymousHost {
        public static readonly SimpleAnonymousHost Simple = new SimpleAnonymousHost ();
 
        bool yields;
-       ArrayList anonymous_methods;
 
        public static SimpleAnonymousHost GetSimple () {
                Simple.yields = false;
-               Simple.anonymous_methods = null;
                return Simple;
        }
 
@@ -5698,22 +5700,11 @@ public class SimpleAnonymousHost : IAnonymousHost {
        {
                yields = true;
        }
-
-       public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
-       {
-               if (anonymous_methods == null)
-                       anonymous_methods = new ArrayList ();
-               anonymous_methods.Add (anonymous);
-       }
-
+       
        public void Propagate (IAnonymousHost real_host)
        {
                if (yields)
                        real_host.SetYields ();
-               if (anonymous_methods != null) {
-                       foreach (AnonymousMethodExpression ame in anonymous_methods)
-                               real_host.AddAnonymousMethod (ame);
-               }
        }
 }
 
@@ -5722,10 +5713,10 @@ public class SimpleAnonymousHost : IAnonymousHost {
 // </summary>
 struct OperatorDeclaration {
        public readonly Operator.OpType optype;
-       public readonly Expression ret_type;
+       public readonly FullNamedExpression ret_type;
        public readonly Location location;
 
-       public OperatorDeclaration (Operator.OpType op, Expression ret_type, Location location)
+       public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
        {
                optype = op;
                this.ret_type = ret_type;
@@ -5843,7 +5834,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
                LocalVariableReference var;
                var = new LocalVariableReference (implicit_block, decl.identifier, loc);
 
-               assign = new Assign (var, expr, decl.Location);
+               assign = new SimpleAssign (var, expr, decl.Location);
 
                implicit_block.AddStatement (new StatementExpression (assign));
        }
@@ -5919,9 +5910,8 @@ static CSharpParser ()
        oob_stack = new Stack ();
 }
 
-public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
+public CSharpParser (SeekableStreamReader reader, CompilationUnit file, ArrayList defines)
 {
-       this.name = file.Name;
        this.file = file;
        current_namespace = new NamespaceEntry (null, file, null);
        current_class = current_namespace.SlaveDeclSpace;
@@ -6016,15 +6006,9 @@ start_anonymous (bool lambda, Parameters parameters, Location loc)
 
        current_local_parameters = parameters;
 
-       ToplevelBlock top_current_block = current_block == null ? null : current_block.Toplevel;
-
        current_anonymous_method = lambda 
-               ? new LambdaExpression (
-                       current_anonymous_method, current_generic_method, current_container,
-                       parameters, top_current_block, loc) 
-               : new AnonymousMethodExpression (
-                       current_anonymous_method, current_generic_method, current_container,
-                       parameters, top_current_block, loc);
+               ? new LambdaExpression (current_container, parameters, loc) 
+               : new AnonymousMethodExpression (current_container, parameters, loc);
 
        // Force the next block to be created as a ToplevelBlock
        parsing_anonymous_method = true;
@@ -6034,8 +6018,7 @@ start_anonymous (bool lambda, Parameters parameters, Location loc)
  * Completes the anonymous method processing, if lambda_expr is null, this
  * means that we have a Statement instead of an Expression embedded 
  */
-AnonymousMethodExpression 
-end_anonymous (ToplevelBlock anon_block, Location loc)
+AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block, Location loc)
 {
        AnonymousMethodExpression retval;
 
@@ -6044,9 +6027,6 @@ end_anonymous (ToplevelBlock anon_block, Location loc)
                retval = null;
        } else  {
                current_anonymous_method.Block = anon_block;
-               if ((anonymous_host != null) && (current_anonymous_method.Parent == null))
-                       anonymous_host.AddAnonymousMethod (current_anonymous_method);
-
                retval = current_anonymous_method;
        }