// Author:
// Miguel de Icaza (miguel@ximian.com)
//
-// (C) 2001, 2002, 2003 Ximian, Inc.
-// (C) 2004 Novell, Inc.
+// Copyright 2001, 2002, 2003 Ximian, Inc.
+// Copyright 2004 Novell, Inc.
//
//
//
// Only remove it if you need to debug locally on your tree.
//
-#define PRODUCTION
+//#define PRODUCTION
using System;
using System.IO;
/// </summary>
public class CodeGen {
static AppDomain current_domain;
- static public SymbolWriter SymbolWriter;
public static AssemblyClass Assembly;
- public static ModuleClass Module;
static CodeGen ()
{
public static void Reset ()
{
Assembly = new AssemblyClass ();
- Module = new ModuleClass (RootContext.Unsafe);
}
public static string Basename (string name)
static public string FileName;
+#if MS_COMPATIBLE
+ const AssemblyBuilderAccess COMPILER_ACCESS = 0;
+#else
+ /* Keep this in sync with System.Reflection.Emit.AssemblyBuilder */
+ const AssemblyBuilderAccess COMPILER_ACCESS = (AssemblyBuilderAccess) 0x800;
+#endif
+
//
- // Initializes the symbol writer
+ // Initializes the code generator variables for interactive use (repl)
//
- static void InitializeSymbolWriter (string filename)
+ static public void InitDynamic (string name)
{
- SymbolWriter = SymbolWriter.GetSymbolWriter (Module.Builder, filename);
-
- //
- // If we got an ISymbolWriter instance, initialize it.
- //
- if (SymbolWriter == null) {
- Report.Warning (
- -18, 1, "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll). This is normally an installation problem. Please make sure to compile and install the mcs/class/Mono.CompilerServices.SymbolWriter directory.");
- return;
- }
+ current_domain = AppDomain.CurrentDomain;
+ AssemblyName an = Assembly.GetAssemblyName (name, name);
+
+ Assembly.Builder = current_domain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run | COMPILER_ACCESS);
+ RootContext.ToplevelTypes = new ModuleContainer (true);
+ RootContext.ToplevelTypes.Builder = Assembly.Builder.DefineDynamicModule (Basename (name), false);
+ Assembly.Name = Assembly.Builder.GetName ();
}
-
+
//
// Initializes the code generator variables
//
if (an.KeyPair != null) {
// If we are going to strong name our assembly make
// sure all its refs are strong named
- foreach (Assembly a in RootNamespace.Global.Assemblies) {
+ foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
AssemblyName ref_name = a.GetName ();
byte [] b = ref_name.GetPublicKeyToken ();
if (b == null || b.Length == 0) {
current_domain = AppDomain.CurrentDomain;
try {
-#if MS_COMPATIBLE
- const AssemblyBuilderAccess COMPILER_ACCESS = 0;
-#else
- /* Keep this in sync with System.Reflection.Emit.AssemblyBuilder */
- const AssemblyBuilderAccess COMPILER_ACCESS = (AssemblyBuilderAccess) 0x800;
-#endif
-
Assembly.Builder = current_domain.DefineDynamicAssembly (an,
- AssemblyBuilderAccess.Save | COMPILER_ACCESS, Dirname (name));
+ AssemblyBuilderAccess.RunAndSave | COMPILER_ACCESS, Dirname (name));
}
catch (ArgumentException) {
// specified key may not be exportable outside it's container
return false;
}
-#if GMCS_SOURCE
// Get the complete AssemblyName from the builder
// (We need to get the public key and token)
Assembly.Name = Assembly.Builder.GetName ();
-#endif
//
// Pass a path-less name to DefineDynamicModule. Wonder how
// If the third argument is true, the ModuleBuilder will dynamically
// load the default symbol writer.
//
- Module.Builder = Assembly.Builder.DefineDynamicModule (
- Basename (name), Basename (output), false);
-
- if (want_debugging_support)
- InitializeSymbolWriter (output);
+ try {
+ RootContext.ToplevelTypes.Builder = Assembly.Builder.DefineDynamicModule (
+ Basename (name), Basename (output), want_debugging_support);
+
+#if !MS_COMPATIBLE
+ // TODO: We should use SymbolWriter from DefineDynamicModule
+ if (want_debugging_support && !SymbolWriter.Initialize (RootContext.ToplevelTypes.Builder, output)) {
+ Report.Error (40, "Unexpected debug information initialization error `{0}'",
+ "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll)");
+ return false;
+ }
+#endif
+ } catch (ExecutionEngineException e) {
+ Report.Error (40, "Unexpected debug information initialization error `{0}'",
+ e.Message);
+ return false;
+ }
return true;
}
- static public void Save (string name)
+ static public void Save (string name, bool saveDebugInfo)
{
try {
Assembly.Builder.Save (Basename (name));
-
- if (SymbolWriter != null)
- SymbolWriter.WriteSymbolFile ();
}
catch (COMException) {
if ((RootContext.StrongNameKeyFile == null) || (!RootContext.StrongNameDelaySign))
}
catch (System.IO.IOException io) {
Report.Error (16, "Could not write to file `"+name+"', cause: " + io.Message);
+ return;
}
catch (System.UnauthorizedAccessException ua) {
Report.Error (16, "Could not write to file `"+name+"', cause: " + ua.Message);
+ return;
+ }
+
+ //
+ // Write debuger symbol file
+ //
+ if (saveDebugInfo)
+ SymbolWriter.WriteSymbolFile ();
}
- }
}
+ /// <summary>
+ /// An interface to hold all the information needed in the resolving phase.
+ /// </summary>
public interface IResolveContext
{
DeclSpace DeclContainer { get; }
InferReturnType = 1 << 9,
- InCompoundAssignment = 1 << 10
+ InCompoundAssignment = 1 << 10,
+
+ OmitDebuggingInfo = 1 << 11
}
Flags flags;
/// So this reflects the low-level staticness of the method, while
/// IsStatic represents the semantic, high-level staticness.
/// </summary>
- public bool MethodIsStatic;
+ //public bool MethodIsStatic;
/// <summary>
/// The value that is allowed to be returned or NULL if there is no
/// </summary>
public bool HasReturnLabel;
- /// <summary>
- /// Whether we are inside an iterator block.
- /// </summary>
- public bool InIterator;
-
/// <summary>
/// Whether we are in a `fixed' initialization
/// </summary>
/// <summary>
/// Whether we are inside an anonymous method.
/// </summary>
- public AnonymousContainer CurrentAnonymousMethod;
+ public AnonymousExpression CurrentAnonymousMethod;
/// <summary>
/// Location for this EmitContext
Emitting
}
- public static EmitContext TempEc;
-
bool isAnonymousMethodAllowed = true;
Phase current_phase;
if (return_type == null)
throw new ArgumentNullException ("return_type");
-#if GMCS_SOURCE
- if ((return_type is TypeBuilder) && return_type.IsGenericTypeDefinition)
- throw new InternalErrorException ();
-#endif
IsStatic = (code_flags & Modifiers.STATIC) != 0;
- MethodIsStatic = IsStatic;
- InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0;
ReturnType = return_type;
IsConstructor = is_constructor;
CurrentBlock = null;
{
}
+ // IResolveContext.DeclContainer
public DeclSpace DeclContainer {
get { return decl_space; }
set { decl_space = value; }
}
+ // IResolveContext.GenericDeclContainer
public DeclSpace GenericDeclContainer {
get { return DeclContainer; }
}
get { return (flags & Flags.InferReturnType) != 0; }
}
+ // IResolveContext.IsInObsoleteScope
public bool IsInObsoleteScope {
get {
// Disables obsolete checks when probing is on
get { return (flags & Flags.ProbingMode) != 0; }
}
+ // IResolveContext.IsInUnsafeScope
public bool IsInUnsafeScope {
get { return InUnsafe || ResolveContext.IsInUnsafeScope; }
}
public bool IsInCompoundAssignment {
get { return (flags & Flags.InCompoundAssignment) != 0; }
- }
+ }
+
+ public bool IsVariableCapturingRequired {
+ get {
+ return !IsInProbingMode && (CurrentBranching == null || !CurrentBranching.CurrentUsageVector.IsUnreachable);
+ }
+ }
public FlowBranching CurrentBranching {
get { return current_flow_branching; }
}
+ public bool OmitDebuggingInfo {
+ get { return (flags & Flags.OmitDebuggingInfo) != 0; }
+ set {
+ if (value)
+ flags |= Flags.OmitDebuggingInfo;
+ else
+ flags &= ~Flags.OmitDebuggingInfo;
+ }
+ }
+
// <summary>
// Starts a new code branching. This inherits the state of all local
// variables and parameters from the current branching.
// </summary>
public FlowBranching StartFlowBranching (Block block)
{
- FlowBranching.BranchingType type;
-
- if ((CurrentBranching != null) &&
- (CurrentBranching.Type == FlowBranching.BranchingType.Switch))
- type = FlowBranching.BranchingType.SwitchSection;
- else
- type = FlowBranching.BranchingType.Block;
-
flags |= Flags.DoFlowAnalysis;
current_flow_branching = FlowBranching.CreateBranching (
- CurrentBranching, type, block, block.StartLocation);
+ CurrentBranching, FlowBranching.BranchingType.Block, block, block.StartLocation);
return current_flow_branching;
}
+ public FlowBranchingTryCatch StartFlowBranching (TryCatch stmt)
+ {
+ FlowBranchingTryCatch branching = new FlowBranchingTryCatch (CurrentBranching, stmt);
+ current_flow_branching = branching;
+ return branching;
+ }
+
public FlowBranchingException StartFlowBranching (ExceptionStatement stmt)
{
FlowBranchingException branching = new FlowBranchingException (CurrentBranching, stmt);
return branching;
}
- public FlowBranchingToplevel StartFlowBranching (ToplevelBlock stmt)
+ public FlowBranchingIterator StartFlowBranching (Iterator iterator)
{
- FlowBranchingToplevel branching = new FlowBranchingToplevel (CurrentBranching, stmt);
+ FlowBranchingIterator branching = new FlowBranchingIterator (CurrentBranching, iterator);
current_flow_branching = branching;
return branching;
}
- // <summary>
- // Ends a code branching. Merges the state of locals and parameters
- // from all the children of the ending branching.
- // </summary>
- public FlowBranching.UsageVector DoEndFlowBranching ()
+ public FlowBranchingToplevel StartFlowBranching (ToplevelBlock stmt)
{
- FlowBranching old = current_flow_branching;
- current_flow_branching = current_flow_branching.Parent;
-
- return current_flow_branching.MergeChild (old);
+ FlowBranchingToplevel branching = new FlowBranchingToplevel (CurrentBranching, stmt);
+ current_flow_branching = branching;
+ return branching;
}
// <summary>
// </summary>
public bool EndFlowBranching ()
{
- FlowBranching.UsageVector vector = DoEndFlowBranching ();
+ FlowBranching old = current_flow_branching;
+ current_flow_branching = current_flow_branching.Parent;
+ FlowBranching.UsageVector vector = current_flow_branching.MergeChild (old);
return vector.IsUnreachable;
}
// Kills the current code branching. This throws away any changed state
// information and should only be used in case of an error.
// </summary>
+ // FIXME: this is evil
public void KillFlowBranching ()
{
current_flow_branching = current_flow_branching.Parent;
{
if (CurrentAnonymousMethod == null)
return false;
+
+ // FIXME: IsIterator is too aggressive, we should capture only if child
+ // block contains yield
if (CurrentAnonymousMethod.IsIterator)
return true;
+
return local.Block.Toplevel != CurrentBlock.Toplevel;
}
EmitMeta (block);
current_phase = Phase.Emitting;
+#if PRODUCTION
+ try {
+#endif
EmitResolvedTopBlock (block, unreachable);
+#if PRODUCTION
+ } catch (Exception e){
+ Console.WriteLine ("Exception caught by the compiler while emitting:");
+ Console.WriteLine (" Block that caused the problem begin at: " + block.loc);
+
+ Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+ throw;
+ }
+#endif
}
}
bool resolved;
-
+ bool unreachable;
+
public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block,
- Parameters ip, IMethodData md, out bool unreachable)
+ ParametersCompiled ip, IMethodData md, out bool unreachable)
{
+ if (resolved) {
+ unreachable = this.unreachable;
+ return true;
+ }
+
current_phase = Phase.Resolving;
-
unreachable = false;
- if (resolved)
- return true;
-
if (!loc.IsNull)
CurrentFile = loc.File;
if (!block.ResolveMeta (this, ip))
return false;
- if ((md != null) && (md.Iterator != null)) {
- if (!md.Iterator.Define (this))
- return false;
- }
-
using (this.With (EmitContext.Flags.DoFlowAnalysis, true)) {
FlowBranchingToplevel top_level;
if (anonymous_method_host != null)
bool flow_unreachable = top_level.End ();
if (flow_unreachable)
- unreachable = true;
+ this.unreachable = unreachable = true;
}
#if PRODUCTION
} catch (Exception e) {
}
}
- if (!block.CompleteContexts (this))
- return false;
-
resolved = true;
return true;
}
// this case.
//
- bool in_iterator = (CurrentAnonymousMethod != null) &&
- CurrentAnonymousMethod.IsIterator && InIterator;
-
- if ((block != null) && block.IsDestructor) {
- // Nothing to do; S.R.E automatically emits a leave.
- } else if (HasReturnLabel || (!unreachable && !in_iterator)) {
+ if (HasReturnLabel || !unreachable) {
if (return_type != TypeManager.void_type)
ig.Emit (OpCodes.Ldloc, TemporaryReturn ());
ig.Emit (OpCodes.Ret);
/// This is called immediately before emitting an IL opcode to tell the symbol
/// writer to which source line this opcode belongs.
/// </summary>
- public void Mark (Location loc, bool check_file)
+ public void Mark (Location loc)
{
- if ((CodeGen.SymbolWriter == null) || loc.IsNull)
+ if (!SymbolWriter.HasSymbolWriter || OmitDebuggingInfo || loc.IsNull)
return;
- if (check_file && (CurrentFile != loc.File))
- return;
-
- CodeGen.SymbolWriter.MarkSequencePoint (ig, loc.Row, loc.Column);
+ SymbolWriter.MarkSequencePoint (ig, loc);
}
public void DefineLocalVariable (string name, LocalBuilder builder)
{
- if (CodeGen.SymbolWriter == null)
- return;
-
- CodeGen.SymbolWriter.DefineLocalVariable (name, builder);
+ SymbolWriter.DefineLocalVariable (name, builder);
}
public void BeginScope ()
{
ig.BeginScope();
-
- if (CodeGen.SymbolWriter != null)
- CodeGen.SymbolWriter.OpenScope(ig);
+ SymbolWriter.OpenScope(ig);
}
public void EndScope ()
{
ig.EndScope();
-
- if (CodeGen.SymbolWriter != null)
- CodeGen.SymbolWriter.CloseScope(ig);
+ SymbolWriter.CloseScope(ig);
}
/// <summary>
public void FreeTemporaryLocal (LocalBuilder b, Type t)
{
- Stack s;
-
if (temporary_storage == null) {
temporary_storage = new Hashtable ();
temporary_storage [t] = b;
temporary_storage [t] = b;
return;
}
- if (o is Stack) {
- s = (Stack) o;
- } else {
+ Stack s = o as Stack;
+ if (s == null) {
s = new Stack ();
s.Push (o);
temporary_storage [t] = s;
throw new Exception ("NeedReturnLabel called from Emit phase, should only be called during Resolve");
}
- if (!InIterator && !HasReturnLabel)
+ if (!HasReturnLabel)
HasReturnLabel = true;
}
OptAttributes.Emit ();
}
- protected Attribute ResolveAttribute (Type a_type)
+ protected Attribute ResolveAttribute (PredefinedAttribute a_type)
{
Attribute a = OptAttributes.Search (a_type);
if (a != null) {
public Attribute ClsCompliantAttribute;
ListDictionary declarative_security;
-#if GMCS_SOURCE
bool has_extension_method;
public AssemblyName Name;
MethodInfo add_type_forwarder;
ListDictionary emitted_forwarders;
-#endif
// Module is here just because of error messages
static string[] attribute_targets = new string [] { "assembly", "module" };
public AssemblyClass (): base ()
{
-#if GMCS_SOURCE
wrap_non_exception_throws = true;
-#endif
}
public bool HasExtensionMethods {
set {
-#if GMCS_SOURCE
has_extension_method = value;
-#endif
}
}
public void Resolve ()
{
+ if (RootContext.Unsafe) {
+ //
+ // Emits [assembly: SecurityPermissionAttribute (SecurityAction.RequestMinimum, SkipVerification = true)]
+ // when -unsafe option was specified
+ //
+
+ Location loc = Location.Null;
+
+ MemberAccess system_security_permissions = new MemberAccess (new MemberAccess (
+ new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Security", loc), "Permissions", loc);
+
+ ArrayList pos = new ArrayList (1);
+ pos.Add (new Argument (new MemberAccess (new MemberAccess (system_security_permissions, "SecurityAction", loc), "RequestMinimum")));
+
+ ArrayList named = new ArrayList (1);
+ named.Add (new DictionaryEntry ("SkipVerification", new Argument (new BoolLiteral (true, loc))));
+
+ GlobalAttribute g = new GlobalAttribute (new NamespaceEntry (null, null, null), "assembly", system_security_permissions,
+ "SecurityPermissionAttribute", new object[] { pos, named }, loc, false);
+ g.AttachTo (this);
+
+ if (g.Resolve () != null) {
+ declarative_security = new ListDictionary ();
+ g.ExtractSecurityPermissionSet (declarative_security);
+ }
+ }
+
if (OptAttributes == null)
return;
if (!OptAttributes.CheckTargets())
return;
- ClsCompliantAttribute = ResolveAttribute (TypeManager.cls_compliant_attribute_type);
+ ClsCompliantAttribute = ResolveAttribute (PredefinedAttributes.Get.CLSCompliant);
+
if (ClsCompliantAttribute != null) {
is_cls_compliant = ClsCompliantAttribute.GetClsCompliantAttributeValue ();
}
-#if GMCS_SOURCE
- Attribute a = ResolveAttribute (TypeManager.runtime_compatibility_attr_type);
+ Attribute a = ResolveAttribute (PredefinedAttributes.Get.RuntimeCompatibility);
if (a != null) {
object val = a.GetPropertyValue ("WrapNonExceptionThrows");
if (val != null)
- wrap_non_exception_throws = (bool)val;
+ wrap_non_exception_throws = (bool) val;
}
-#endif
}
// fix bug #56621
// are loaded yet.
// TODO: Does not handle quoted attributes properly
switch (a.Name) {
- case "AssemblyKeyFile":
- case "AssemblyKeyFileAttribute":
- case "System.Reflection.AssemblyKeyFileAttribute":
- if (RootContext.StrongNameKeyFile != null) {
- Report.SymbolRelatedToPreviousError (a.Location, a.Name);
- Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
- "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
- }
- else {
- string value = a.GetString ();
- if (value.Length != 0)
- RootContext.StrongNameKeyFile = value;
- }
- break;
- case "AssemblyKeyName":
- case "AssemblyKeyNameAttribute":
- case "System.Reflection.AssemblyKeyNameAttribute":
- if (RootContext.StrongNameKeyContainer != null) {
- Report.SymbolRelatedToPreviousError (a.Location, a.Name);
- Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
+ case "AssemblyKeyFile":
+ case "AssemblyKeyFileAttribute":
+ case "System.Reflection.AssemblyKeyFileAttribute":
+ if (RootContext.StrongNameKeyFile != null) {
+ Report.SymbolRelatedToPreviousError (a.Location, a.Name);
+ Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
+ "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
+ } else {
+ string value = a.GetString ();
+ if (value.Length != 0)
+ RootContext.StrongNameKeyFile = value;
+ }
+ break;
+ case "AssemblyKeyName":
+ case "AssemblyKeyNameAttribute":
+ case "System.Reflection.AssemblyKeyNameAttribute":
+ if (RootContext.StrongNameKeyContainer != null) {
+ Report.SymbolRelatedToPreviousError (a.Location, a.Name);
+ Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
"keycontainer", "System.Reflection.AssemblyKeyNameAttribute");
- }
- else {
- string value = a.GetString ();
- if (value.Length != 0)
- RootContext.StrongNameKeyContainer = value;
- }
- break;
- case "AssemblyDelaySign":
- case "AssemblyDelaySignAttribute":
- case "System.Reflection.AssemblyDelaySignAttribute":
- RootContext.StrongNameDelaySign = a.GetBoolean ();
- break;
+ } else {
+ string value = a.GetString ();
+ if (value.Length != 0)
+ RootContext.StrongNameKeyContainer = value;
+ }
+ break;
+ case "AssemblyDelaySign":
+ case "AssemblyDelaySignAttribute":
+ case "System.Reflection.AssemblyDelaySignAttribute":
+ RootContext.StrongNameDelaySign = a.GetBoolean ();
+ break;
}
}
}
-
+
AssemblyName an = new AssemblyName ();
an.Name = Path.GetFileNameWithoutExtension (name);
Report.Error (1548, "Error during assembly signing. " + text);
}
-#if GMCS_SOURCE
bool CheckInternalsVisibleAttribute (Attribute a)
{
string assembly_name = a.GetString ();
AssemblyName aname = null;
try {
+#if GMCS_SOURCE
aname = new AssemblyName (assembly_name);
+#else
+ throw new NotSupportedException ();
+#endif
} catch (FileLoadException) {
} catch (ArgumentException) {
}
return true;
}
-#endif
static bool IsValidAssemblyVersion (string version)
{
return true;
}
- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
{
- if (TypeManager.IsSubclassOf (a.Type, TypeManager.security_attr_type) && a.CheckSecurityActionValidity (true)) {
+ if (a.IsValidSecurityAttribute ()) {
if (declarative_security == null)
declarative_security = new ListDictionary ();
return;
}
- if (a.Type == TypeManager.assembly_culture_attribute_type) {
+ if (a.Type == pa.AssemblyCulture) {
string value = a.GetString ();
if (value == null || value.Length == 0)
return;
}
}
- if (a.Type == TypeManager.assembly_version_attribute_type) {
+ if (a.Type == pa.AssemblyVersion) {
string value = a.GetString ();
if (value == null || value.Length == 0)
return;
}
}
-#if GMCS_SOURCE
- if (a.Type == TypeManager.internals_visible_attr_type && !CheckInternalsVisibleAttribute (a))
+ if (a.Type == pa.InternalsVisibleTo && !CheckInternalsVisibleAttribute (a))
return;
- if (a.Type == TypeManager.type_forwarder_attr_type) {
+ if (a.Type == pa.TypeForwarder) {
Type t = a.GetArgumentType ();
if (t == null || TypeManager.HasElementType (t)) {
Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute");
return;
}
- if (t.IsNested) {
+ if (t.DeclaringType != null) {
Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type",
TypeManager.CSharpName (t));
return;
}
- if (t.IsGenericType) {
+ if (TypeManager.IsGenericType (t)) {
Report.Error (733, a.Location, "Cannot forward generic type `{0}'", TypeManager.CSharpName (t));
return;
}
return;
}
- if (a.Type == TypeManager.extension_attribute_type) {
+ if (a.Type == pa.Extension) {
a.Error_MisusedExtensionAttribute ();
return;
}
-#endif
- Builder.SetCustomAttribute (customBuilder);
+
+ Builder.SetCustomAttribute (cb);
}
public override void Emit (TypeContainer tc)
{
base.Emit (tc);
-#if GMCS_SOURCE
if (has_extension_method)
- Builder.SetCustomAttribute (TypeManager.extension_attribute_attr);
+ PredefinedAttributes.Get.Extension.EmitAttribute (Builder);
// FIXME: Does this belong inside SRE.AssemblyBuilder instead?
- if (OptAttributes == null || !OptAttributes.Contains (TypeManager.runtime_compatibility_attr_type)) {
- ConstructorInfo ci = TypeManager.GetConstructor (
- TypeManager.runtime_compatibility_attr_type, Type.EmptyTypes);
+ PredefinedAttribute pa = PredefinedAttributes.Get.RuntimeCompatibility;
+ if (pa.IsDefined && (OptAttributes == null || !OptAttributes.Contains (pa))) {
+ ConstructorInfo ci = TypeManager.GetPredefinedConstructor (
+ pa.Type, Location.Null, Type.EmptyTypes);
PropertyInfo [] pis = new PropertyInfo [1];
- pis [0] = TypeManager.GetProperty (
- TypeManager.runtime_compatibility_attr_type, "WrapNonExceptionThrows");
+ pis [0] = TypeManager.GetPredefinedProperty (pa.Type,
+ "WrapNonExceptionThrows", Location.Null, TypeManager.bool_type);
object [] pargs = new object [1];
pargs [0] = true;
Builder.SetCustomAttribute (new CustomAttributeBuilder (ci, new object [0], pis, pargs));
}
-#endif
if (declarative_security != null) {
}
}
}
-
- public class ModuleClass : CommonAssemblyModulClass {
- // TODO: make it private and move all builder based methods here
- public ModuleBuilder Builder;
- bool m_module_is_unsafe;
- bool has_default_charset;
-
- public CharSet DefaultCharSet = CharSet.Ansi;
- public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
-
- static string[] attribute_targets = new string [] { "module" };
-
- public ModuleClass (bool is_unsafe)
- {
- m_module_is_unsafe = is_unsafe;
- }
-
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Module;
- }
- }
-
- public override bool IsClsComplianceRequired ()
- {
- return CodeGen.Assembly.IsClsCompliant;
- }
-
- public override void Emit (TypeContainer tc)
- {
- base.Emit (tc);
-
- if (!m_module_is_unsafe)
- return;
-
- if (TypeManager.unverifiable_code_ctor == null) {
- Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute.");
- return;
- }
-
- Builder.SetCustomAttribute (new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0]));
- }
-
- public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
- {
- if (a.Type == TypeManager.cls_compliant_attribute_type) {
- if (CodeGen.Assembly.ClsCompliantAttribute == null) {
- Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
- }
- else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
- Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
- Report.Error (3017, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
- return;
- }
- }
-
- Builder.SetCustomAttribute (customBuilder);
- }
-
- public bool HasDefaultCharSet {
- get {
- return has_default_charset;
- }
- }
-
- /// <summary>
- /// It is called very early therefore can resolve only predefined attributes
- /// </summary>
- public void Resolve ()
- {
-#if GMCS_SOURCE
- if (OptAttributes == null)
- return;
-
- if (!OptAttributes.CheckTargets())
- return;
-
- Attribute a = ResolveAttribute (TypeManager.default_charset_type);
- if (a != null) {
- has_default_charset = true;
- DefaultCharSet = a.GetCharSetValue ();
- switch (DefaultCharSet) {
- case CharSet.Ansi:
- case CharSet.None:
- break;
- case CharSet.Auto:
- DefaultCharSetType = TypeAttributes.AutoClass;
- break;
- case CharSet.Unicode:
- DefaultCharSetType = TypeAttributes.UnicodeClass;
- break;
- default:
- Report.Error (1724, a.Location, "Value specified for the argument to 'System.Runtime.InteropServices.DefaultCharSetAttribute' is not valid");
- break;
- }
- }
-#endif
- }
-
- public override string[] ValidAttributeTargets {
- get {
- return attribute_targets;
- }
- }
- }
}