Merge branch 'master' into msbuilddll2
[mono.git] / mcs / mcs / attribute.cs
index a76a59f753786e76949f3cfc7594075d7dfec38e..2152674d2da63e7d766bea3b3f36bde38a0a0b18 100644 (file)
@@ -284,7 +284,8 @@ namespace Mono.CSharp {
                /// </summary>
                void ResolveAttributeType (bool comparisonOnly)
                {
-                       SessionReportPrinter resolve_printer = new SessionReportPrinter ();
+                       var resolve_printer = new SessionReportPrinter ();
+                       SessionReportPrinter secondary_printer = null;
                        ReportPrinter prev_recorder = Report.SetPrinter (resolve_printer);
 
                        bool t1_is_attr = false;
@@ -297,20 +298,25 @@ namespace Mono.CSharp {
 
                        try {
                                t1 = expression.ResolveAsType (context);
-                               if (t1 != null)
-                                       t1_is_attr = t1.IsAttribute;
-
                                resolve_printer.EndSession ();
 
+                               if (t1 != null && resolve_printer.ErrorsCount == 0)
+                                       t1_is_attr = t1.IsAttribute;
+
                                if (nameEscaped) {
                                        t2 = null;
                                } else {
                                        expanded = (ATypeNameExpression) expression.Clone (null);
                                        expanded.Name += "Attribute";
 
+                                       secondary_printer = new SessionReportPrinter ();
+                                       Report.SetPrinter (secondary_printer);
                                        t2 = expanded.ResolveAsType (context);
-                                       if (t2 != null)
+                                       secondary_printer.EndSession ();
+                                       if (t2 != null && secondary_printer.ErrorsCount == 0)
                                                t2_is_attr = t2.IsAttribute;
+
+                                       secondary_printer.EndSession ();
                                }
                        } finally {
                                context.Module.Compiler.Report.SetPrinter (prev_recorder);
@@ -341,17 +347,25 @@ namespace Mono.CSharp {
 
                        resolve_error = true;
 
-                       if (t1 != null) {
-                               resolve_printer.Merge (prev_recorder);
+                       if (t1 != null) {       
+                               if (resolve_printer.IsEmpty) {
+                                       Report.SymbolRelatedToPreviousError (t1);
+                                       Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
+                               } else {
+                                       resolve_printer.Merge (prev_recorder);
+                               }
 
-                               Report.SymbolRelatedToPreviousError (t1);
-                               Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
                                return;
                        }
 
                        if (t2 != null) {
-                               Report.SymbolRelatedToPreviousError (t2);
-                               Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
+                               if (secondary_printer.IsEmpty) {
+                                       Report.SymbolRelatedToPreviousError (t2);
+                                       Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
+                               } else {
+                                       secondary_printer.Merge (prev_recorder);
+                               }
+
                                return;
                        }
 
@@ -385,6 +399,19 @@ namespace Mono.CSharp {
                        return HasSecurityAttribute && IsSecurityActionValid ();
                }
 
+               static bool IsValidMethodImplOption (int value)
+               {
+                       //
+                       // Allow to use AggressiveInlining on any runtime/corlib
+                       //
+                       MethodImplOptions all = (MethodImplOptions) 256;
+                       foreach (MethodImplOptions v in System.Enum.GetValues (typeof (MethodImplOptions))) {
+                               all |= v;
+                       }
+
+                       return ((MethodImplOptions) value | all) == all;
+               }
+
                static bool IsValidArgumentType (TypeSpec t)
                {
                        if (t.IsArray) {
@@ -1025,10 +1052,14 @@ namespace Mono.CSharp {
                                                                        if (string.IsNullOrEmpty (value))
                                                                                Error_AttributeEmitError ("DllName cannot be empty or null");
                                                                }
-                                                       } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
-                                                               !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
-                                                               Error_AttributeEmitError ("Incorrect argument value.");
-                                                               return;
+                                                       } else if (Type == predefined.MethodImpl) {
+                                                               if (pos_args.Count == 1) {
+                                                                       var value = (int) ((Constant) arg_expr).GetValueAsLong ();
+
+                                                                       if (!IsValidMethodImplOption (value)) {
+                                                                               Error_AttributeEmitError ("Incorrect argument value");
+                                                                       }
+                                                               }
                                                        }
                                                }
 
@@ -1055,7 +1086,7 @@ namespace Mono.CSharp {
                                cdata = encoder.ToArray ();
                        }
 
-                       if (!ctor.DeclaringType.IsConditionallyExcluded (context, Location)) {
+                       if (!ctor.DeclaringType.IsConditionallyExcluded (context)) {
                                try {
                                        foreach (Attributable target in targets)
                                                target.ApplyAttributeBuilder (this, ctor, cdata, predefined);
@@ -1141,7 +1172,7 @@ namespace Mono.CSharp {
 
                public Attributes (List<Attribute> attrs)
                {
-                       Attrs = attrs;
+                       Attrs = attrs ?? new List<Attribute> ();
                }
 
                public void AddAttribute (Attribute attr)
@@ -1633,6 +1664,8 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute UnsafeValueType;
                public readonly PredefinedAttribute UnmanagedFunctionPointer;
                public readonly PredefinedDebuggerBrowsableAttribute DebuggerBrowsable;
+               public readonly PredefinedAttribute DebuggerStepThrough;
+               public readonly PredefinedDebuggableAttribute Debuggable;
 
                // New in .NET 3.5
                public readonly PredefinedAttribute Extension;
@@ -1699,6 +1732,8 @@ namespace Mono.CSharp {
                        UnsafeValueType = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
                        UnmanagedFunctionPointer = new PredefinedAttribute (module, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
                        DebuggerBrowsable = new PredefinedDebuggerBrowsableAttribute (module, "System.Diagnostics", "DebuggerBrowsableAttribute");
+                       DebuggerStepThrough = new PredefinedAttribute (module, "System.Diagnostics", "DebuggerStepThroughAttribute");
+                       Debuggable = new PredefinedDebuggableAttribute (module, "System.Diagnostics", "DebuggableAttribute");
 
                        Extension = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "ExtensionAttribute");
 
@@ -1859,6 +1894,40 @@ namespace Mono.CSharp {
                }
        }
 
+       public class PredefinedDebuggableAttribute : PredefinedAttribute
+       {
+               public PredefinedDebuggableAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
+               }
+
+               public void EmitAttribute (AssemblyBuilder builder, System.Diagnostics.DebuggableAttribute.DebuggingModes modes)
+               {
+                       var atype = module.PredefinedAttributes.Debuggable;
+                       if (!atype.Define ())
+                               return;
+
+                       MethodSpec ctor = null;
+                       foreach (MethodSpec m in MemberCache.FindMembers (atype.TypeSpec, CSharp.Constructor.ConstructorName, true)) {
+                               if (m.Parameters.Count != 1)
+                                       continue;
+
+                               if (m.Parameters.Types[0].Kind == MemberKind.Enum) {
+                                       ctor = m;
+                               }
+                       }
+
+                       if (ctor == null)
+                               return;
+
+                       AttributeEncoder encoder = new AttributeEncoder ();
+                       encoder.Encode ((int) modes);
+                       encoder.EncodeEmptyNamedArguments ();
+
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+               }
+       }
+
        public class PredefinedDecimalAttribute : PredefinedAttribute
        {
                public PredefinedDecimalAttribute (ModuleContainer module, string ns, string name)
@@ -1988,7 +2057,7 @@ namespace Mono.CSharp {
                        if (ac != null) {
                                element = GetTransformationFlags (ac.Element);
                                if (element == null)
-                                       return null;
+                                       return new bool[] { false, false };
 
                                bool[] res = new bool[element.Length + 1];
                                res[0] = false;