// from classes from the arraylist `type_bases'
//
string base_class_name;
+ public Type base_classs_type;
ArrayList type_bases;
}
base.ApplyAttributeBuilder (a, cb);
- }
+ }
public override AttributeTargets AttributeTargets {
get {
TypeAttributes type_attributes = TypeAttr;
- Type ptype;
if (parent != null)
- ptype = parent.ResolveType (ec);
- else
- ptype = null;
+ base_classs_type = parent.ResolveType (ec);
if (IsTopLevel){
if (TypeManager.NamespaceClash (Name, Location)) {
ModuleBuilder builder = CodeGen.Module.Builder;
TypeBuilder = builder.DefineType (
- Name, type_attributes, ptype, null);
+ Name, type_attributes, base_classs_type, null);
+
} else {
TypeBuilder builder = Parent.DefineType ();
if (builder == null)
return null;
TypeBuilder = builder.DefineNestedType (
- Basename, type_attributes, ptype, null);
+ Basename, type_attributes, base_classs_type, null);
}
//
// Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
bool seen_normal_indexers = false;
- foreach (Indexer i in Indexers) {
- if (i.ExplicitInterfaceName == null)
- seen_normal_indexers = true;
- else if (seen_normal_indexers)
- throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
- }
foreach (Indexer i in Indexers) {
string name;
name = i.IndexerName;
- if (i.InterfaceType != null)
+ if (i.InterfaceType != null) {
+ if (seen_normal_indexers)
+ throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
continue;
+ }
+
+ seen_normal_indexers = true;
- if (class_indexer_name == null){
+ if (class_indexer_name == null)
class_indexer_name = name;
- continue;
- }
-
- if (name == class_indexer_name)
- continue;
-
- Report.Error (
- 668, "Two indexers have different names, " +
- " you should use the same name for all your indexers");
+ else if (name != class_indexer_name)
+ Report.Error (668, "Two indexers have different names, " +
+ " you should use the same name for all your indexers");
}
if (seen_normal_indexers && class_indexer_name == null)
return;
}
- protected virtual void VerifyMembers ()
+ protected virtual void VerifyMembers (EmitContext ec)
{
//
// Check for internal or private fields that were never assigned
if (Pending.VerifyPendingMethods ())
return;
- VerifyMembers ();
+ VerifyMembers (ec);
// if (types != null)
// foreach (TypeContainer tc in types)
{
}
- protected override void VerifyMembers ()
+ protected override void VerifyMembers (EmitContext ec)
{
if (Fields != null) {
foreach (Field f in Fields) {
continue;
if (hasExplicitLayout) {
if (f.OptAttributes == null
- || !f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, this)) {
+ || !f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
Report.Error (625, f.Location,
"Instance field of type marked with"
+ " StructLayout(LayoutKind.Explicit) must have a"
}
else {
if (f.OptAttributes != null
- && f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, this)) {
+ && f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
Report.Error (636, f.Location,
"The FieldOffset attribute can only be placed on members of "
+ "types marked with the StructLayout(LayoutKind.Explicit)");
}
}
}
- base.VerifyMembers ();
+ base.VerifyMembers (ec);
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
// Whether this is an operator method.
public bool IsOperator;
+ static string[] attribute_targets = new string [] { "method", "return" };
+
public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
bool is_interface, string name, Attributes attrs,
Parameters parameters, Location loc)
return true;
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
protected override bool VerifyClsCompliance (DeclSpace ds)
{
if (!base.VerifyClsCompliance (ds)) {
public class Method : MethodCore, IIteratorContainer, IMethodData {
public MethodBuilder MethodBuilder;
public MethodData MethodData;
+ ReturnParameter return_attributes;
/// <summary>
/// Modifiers allowed in a class declaration
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
}
return new EmitContext (tc, ds, Location, ig, ReturnType, ModFlags, false);
}
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return GetObsoleteAttribute (ds);
+ }
#endregion
}
public abstract class ConstructorInitializer {
ArrayList argument_list;
- ConstructorInfo parent_constructor;
+ protected ConstructorInfo parent_constructor;
Parameters parameters;
Location loc;
Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
}
}
+
+ /// <summary>
+ /// Method search for base ctor. (We do not cache it).
+ /// </summary>
+ Constructor GetOverloadedConstructor (TypeContainer tc)
+ {
+ if (tc.InstanceConstructors == null)
+ return null;
+
+ foreach (Constructor c in tc.InstanceConstructors) {
+ if (Arguments == null) {
+ if (c.ParameterTypes.Length == 0)
+ return c;
+
+ continue;
+ }
+
+ if (c.ParameterTypes.Length != Arguments.Count)
+ continue;
+
+ for (int i = 0; i < Arguments.Count; ++i)
+ if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type)
+ continue;
+
+ return c;
+ }
+
+ throw new InternalErrorException ();
+ }
+
+ //TODO: implement caching when it will be necessary
+ public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
+ {
+ Constructor ctor = GetOverloadedConstructor (tc);
+ if (ctor == null)
+ return;
+
+ ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
+ if (oa == null)
+ return;
+
+ AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
+ }
}
public class ConstructorBaseInitializer : ConstructorInitializer {
base (argument_list, pars, l)
{
}
+
+ public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
+ if (parent_constructor == null)
+ return;
+
+ TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.base_classs_type);
+ if (type_ds == null) {
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
+
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
+
+ return;
+ }
+
+ base.CheckObsoleteAttribute (type_ds, loc);
+ }
+
}
public class ConstructorThisInitializer : ConstructorInitializer {
ec.IsStatic = false;
}
- Parameters.LabelParameters (ec, ConstructorBuilder,
- OptAttributes, Location);
+ Parameters.LabelParameters (ec, ConstructorBuilder, Location);
SymbolWriter sw = CodeGen.SymbolWriter;
bool generate_debugging = false;
container.EmitFieldInitializers (ec);
}
}
- if (Initializer != null)
+ if (Initializer != null) {
+ Initializer.CheckObsoleteAttribute (container, Location);
Initializer.Emit (ec);
+ }
if ((ModFlags & Modifiers.STATIC) != 0)
container.EmitFieldInitializers (ec);
Block Block { get; }
EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
+ ObsoleteAttribute GetObsoleteAttribute ();
}
//
// Attributes.
//
Attribute dllimport_attribute = null;
- string obsolete = null;
- bool obsolete_error = false;
- public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method, DeclSpace ds)
+ public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method,
+ EmitContext ec)
{
- if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
+ if ((opt_attrs == null) || (opt_attrs.Attrs == null))
return true;
- foreach (AttributeSection asec in opt_attrs.AttributeSections) {
- if (asec.Attributes == null)
- continue;
-
- foreach (Attribute a in asec.Attributes) {
- Type attr_type = a.ResolveType (ds, true);
- if (attr_type == TypeManager.conditional_attribute_type) {
- if (!ApplyConditionalAttribute (a))
- return false;
- } else if (attr_type == TypeManager.obsolete_attribute_type) {
- if (!ApplyObsoleteAttribute (a))
- return false;
- } else if (attr_type == TypeManager.dllimport_type) {
- if (!is_method) {
- Attribute.Error_AttributeNotValidForElement (a, method.Location);
- return false;
- }
- if (!ApplyDllImportAttribute (a))
- return false;
+ foreach (Attribute a in opt_attrs.Attrs) {
+ Type attr_type = a.ResolveType (ec, true);
+ if (attr_type == TypeManager.conditional_attribute_type) {
+ if (!ApplyConditionalAttribute (a))
+ return false;
+ } else if (attr_type == TypeManager.dllimport_type) {
+ if (!is_method) {
+ Attribute.Error_AttributeNotValidForElement (a, method.Location);
+ return false;
}
+ if (!ApplyDllImportAttribute (a))
+ return false;
}
}
return true;
}
- //
- // Applies the `Obsolete' attribute to the method.
- //
- protected virtual bool ApplyObsoleteAttribute (Attribute a)
- {
- if (obsolete != null) {
- Report.Error (579, method.Location, "Duplicate `Obsolete' attribute");
- return false;
- }
-
- obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
- return obsolete != null;
- }
-
//
// Applies the `Conditional' attribute to the method.
//
{
TypeManager.MethodFlags flags = 0;
- if (obsolete != null) {
- if (obsolete_error) {
- Report.Error (619, loc, "Method `" + member.Name +
- "' is obsolete: `" + obsolete + "'");
- return TypeManager.MethodFlags.IsObsoleteError;
- } else
- Report.Warning (618, loc, "Method `" + member.Name +
- "' is obsolete: `" + obsolete + "'");
-
- flags |= TypeManager.MethodFlags.IsObsolete;
- }
-
if (ShouldIgnore (loc))
flags |= TypeManager.MethodFlags.ShouldIgnore;
MethodInfo implementing = null;
string prefix;
+ EmitContext ec = method.CreateEmitContext (container, null);
+
if (method.OptAttributes != null)
- if (!ApplyAttributes (method.OptAttributes, is_method, container))
+ if (!ApplyAttributes (method.OptAttributes, is_method, ec))
return false;
if (member.IsExplicitImpl)
return false;
}
- EmitContext ec = method.CreateEmitContext (container, null);
-
builder = dllimport_attribute.DefinePInvokeMethod (
ec, container.TypeBuilder, method_name, flags,
method.ReturnType, ParameterTypes);
}
TypeManager.AddMethod (builder, this);
+ TypeManager.AddMethod2 (builder, method);
return true;
}
Location loc = method.Location;
Attributes OptAttributes = method.OptAttributes;
- if (OptAttributes != null)
+ if (OptAttributes != null)
OptAttributes.Emit (ec, kind);
if (member is MethodCore)
- ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder,OptAttributes, loc);
+ ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
SymbolWriter sw = CodeGen.SymbolWriter;
Block block = method.Block;
[Flags]
public enum Status : byte { ASSIGNED = 1, USED = 2 }
+ static string[] attribute_targets = new string [] { "field" };
+
//
// The constructor is only exposed to our children
//
return TypeManager.GetFullNameSignature (FieldBuilder);
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
protected override bool VerifyClsCompliance (DeclSpace ds)
{
if (!base.VerifyClsCompliance (ds))
public override bool Define (TypeContainer container)
{
- Type t = container.ResolveType (Type, false, Location);
+ MemberType = container.ResolveType (Type, false, Location);
- if (t == null)
+ if (MemberType == null)
return false;
CheckBase (container);
- if (!container.AsAccessible (t, ModFlags)) {
+ if (!container.AsAccessible (MemberType, ModFlags)) {
Report.Error (52, Location,
"Inconsistent accessibility: field type `" +
- TypeManager.CSharpName (t) + "' is less " +
+ TypeManager.CSharpName (MemberType) + "' is less " +
"accessible than field `" + Name + "'");
return false;
}
- if (t.IsPointer && !UnsafeOK (container))
+ if (MemberType.IsPointer && !UnsafeOK (container))
return false;
if (RootContext.WarningLevel > 1){
}
if ((ModFlags & Modifiers.VOLATILE) != 0){
- if (!t.IsClass){
- Type vt = t;
+ if (!MemberType.IsClass){
+ Type vt = MemberType;
if (TypeManager.IsEnumType (vt))
- vt = TypeManager.EnumToUnderlying (t);
+ vt = TypeManager.EnumToUnderlying (MemberType);
if (!((vt == TypeManager.bool_type) ||
(vt == TypeManager.sbyte_type) ||
if (container is Struct &&
((fa & FieldAttributes.Static) == 0) &&
- t == container.TypeBuilder &&
- !TypeManager.IsBuiltinType (t)){
+ MemberType == container.TypeBuilder &&
+ !TypeManager.IsBuiltinType (MemberType)){
Report.Error (523, Location, "Struct member `" + container.Name + "." + Name +
"' causes a cycle in the structure layout");
return false;
try {
FieldBuilder = container.TypeBuilder.DefineField (
- Name, t, Modifiers.FieldAttr (ModFlags));
+ Name, MemberType, Modifiers.FieldAttr (ModFlags));
TypeManager.RegisterFieldBase (FieldBuilder, this);
}
public class GetMethod: PropertyMethod
{
+ static string[] attribute_targets = new string [] { "method", "return" };
+
public GetMethod (MethodCore method, Accessor accessor):
base (method, accessor)
{
return method.MemberType;
}
}
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
public class SetMethod: PropertyMethod {
+
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
+ ImplicitParameter param_attr;
+
public SetMethod (MethodCore method, Accessor accessor):
base (method, accessor)
{
}
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "param") {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
protected virtual InternalParameters GetParameterInfo (TypeContainer container)
{
Parameter [] parms = new Parameter [1];
return TypeManager.void_type;
}
}
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
- public abstract class PropertyMethod: Attributable, IMethodData {
+ static string[] attribute_targets = new string [] { "property" };
+
+ public abstract class PropertyMethod: Attributable, IMethodData
+ {
protected readonly MethodCore method;
protected MethodData method_data;
Block block;
+ ReturnParameter return_attributes;
+
public PropertyMethod (MethodCore method, Accessor accessor):
base (accessor.Attributes)
{
}
}
+
public override bool IsClsCompliaceRequired(DeclSpace ds)
{
return method.IsClsCompliaceRequired (ds);
{
method_data.Emit (container, this);
block = null;
-
}
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
method_data.MethodBuilder.SetCustomAttribute (cb);
}
return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
}
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return method.GetObsoleteAttribute (method.ds);
+ }
#endregion
}
base.Emit (tc);
}
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
public class Property : PropertyBase, IIteratorContainer {
}
}
- public class Event : FieldBase {
+ /// <summary>
+ /// For case when event is declared like property (with add and remove accessors).
+ /// </summary>
+ public class EventProperty: Event {
+
+ static string[] attribute_targets = new string [] { "event", "property" };
+
+ public EventProperty (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
+ Object init, Attributes attrs, Accessor add, Accessor remove, Location loc)
+ : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
+ {
+ Add = new AddDelegateMethod (this, add);
+ Remove = new RemoveDelegateMethod (this, remove);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event is declared like field.
+ /// </summary>
+ public class EventField: Event {
+
+ static string[] attribute_targets = new string [] { "method", "field", "event" };
+
+ public EventField (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
+ Object init, Attributes attrs, Location loc)
+ : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
+ {
+ Add = new AddDelegateMethod (this);
+ Remove = new RemoveDelegateMethod (this);
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "field") {
+ FieldBuilder.SetCustomAttribute (cb);
+ return;
+ }
- sealed class AddDelegateMethod: DelegateMethod
+ if (a.Target == "method") {
+ AddBuilder.SetCustomAttribute (cb);
+ RemoveBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ public abstract class Event : FieldBase {
+
+ protected sealed class AddDelegateMethod: DelegateMethod
{
public AddDelegateMethod (Event method):
base (method)
}
- sealed class RemoveDelegateMethod: DelegateMethod
+ protected sealed class RemoveDelegateMethod: DelegateMethod
{
public RemoveDelegateMethod (Event method):
base (method)
protected readonly Event method;
protected MethodData method_data;
Block block;
+ ReturnParameter return_attributes;
+ ImplicitParameter param_attr;
+
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
public DelegateMethod (Event method):
base (null)
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ if (a.Target == "param") {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
method_data.MethodBuilder.SetCustomAttribute (cb);
}
public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
{
- return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
+ return new EmitContext (tc, method.ds, Location, ig, ReturnType, method.ModFlags, false);
+ }
+
+ public ObsoleteAttribute GetObsoleteAttribute ()
+ {
+ return method.GetObsoleteAttribute (method.ds);
}
public abstract string MethodName { get; }
#endregion
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
const int AllowedInterfaceModifiers =
Modifiers.NEW;
- readonly DelegateMethod Add, Remove;
+ protected DelegateMethod Add, Remove;
public MyEventBuilder EventBuilder;
public MethodBuilder AddBuilder, RemoveBuilder;
public DeclSpace ds;
- public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
- Object init, Attributes attrs, Accessor add, Accessor remove, Location loc)
- : base (type, mod_flags, is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
- name, init, attrs, loc)
- {
- IsInterface = is_iface;
- this.ds = ds;
-
- Add = new AddDelegateMethod (this, add);
- Remove = new RemoveDelegateMethod (this, remove);
- }
-
public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
Object init, Attributes attrs, Location loc)
: base (type, mod_flags, is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
{
IsInterface = is_iface;
this.ds = ds;
-
- Add = new AddDelegateMethod (this);
- Remove = new RemoveDelegateMethod (this);
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
base.Emit (tc);
}
-
}
//
if (!DoDefine (container))
return false;
- IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
+ if (OptAttributes != null)
+ IndexerName = OptAttributes.ScanForIndexerName (ec);
+
if (IndexerName == null)
IndexerName = "Item";
else {
if (IsExplicitImpl) {
Report.Error (592, Location,
- "Attribute 'IndexerName' is not valid on explicit " +
- "implementations.");
-
+ "Attribute 'IndexerName' is not valid on explicit implementations.");
return false;
}
}
public string MethodName;
public Method OperatorMethod;
+ static string[] attribute_targets = new string [] { "method", "return" };
+
public Operator (OpType type, Expression ret_type, int mod_flags,
Expression arg1type, string arg1name,
Expression arg2type, string arg2name,
param_types [0], param_types [1]);
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
public void SetYields ()
{
ModFlags |= Modifiers.METHOD_YIELDS;