2 // modifiers.cs: Modifier handling.
5 using System
.Reflection
;
7 namespace Mono
.CSharp
{
8 public class Modifiers
{
11 // The ordering of the following 4 constants
12 // has been carefully done.
14 public const int PROTECTED
= 0x0001;
15 public const int PUBLIC
= 0x0002;
16 public const int PRIVATE
= 0x0004;
17 public const int INTERNAL
= 0x0008;
18 public const int NEW
= 0x0010;
19 public const int ABSTRACT
= 0x0020;
20 public const int SEALED
= 0x0040;
21 public const int STATIC
= 0x0080;
22 public const int READONLY
= 0x0100;
23 public const int VIRTUAL
= 0x0200;
24 public const int OVERRIDE
= 0x0400;
25 public const int EXTERN
= 0x0800;
26 public const int VOLATILE
= 0x1000;
27 public const int UNSAFE
= 0x2000;
28 public const int WRITEONLY
= 0x04000;
29 public const int SHADOWS
= 0x08000;
30 public const int DEFAULT
= 0x10000;
31 public const int NONVIRTUAL
= 0x20000;
32 private const int TOP
= 0x20000;
35 // We use this internally to flag that the method contains an iterator
37 public const int METHOD_YIELDS
= 0x8000;
38 public const int METHOD_GENERIC
= 0x10000;
40 public const int Accessibility
=
41 PUBLIC
| PROTECTED
| INTERNAL
| PRIVATE
;
42 public const int AllowedExplicitImplFlags
=
45 static public string Name (int i
)
52 case Modifiers
.PUBLIC
:
54 case Modifiers
.PROTECTED
:
55 s
= "protected"; break;
56 case Modifiers
.INTERNAL
:
57 s
= "internal"; break;
58 case Modifiers
.PRIVATE
:
60 case Modifiers
.ABSTRACT
:
61 s
= "abstract"; break;
62 case Modifiers
.SEALED
:
64 case Modifiers
.STATIC
:
66 case Modifiers
.READONLY
:
67 s
= "readonly"; break;
68 case Modifiers
.VIRTUAL
:
70 case Modifiers
.OVERRIDE
:
71 s
= "override"; break;
72 case Modifiers
.EXTERN
:
74 case Modifiers
.VOLATILE
:
75 s
= "volatile"; break;
76 case Modifiers
.UNSAFE
:
83 public static TypeAttributes
TypeAttr (int mod_flags
, bool is_toplevel
)
88 if ((mod_flags
& PUBLIC
) != 0)
89 t
|= TypeAttributes
.Public
;
90 if ((mod_flags
& PRIVATE
) != 0)
91 t
|= TypeAttributes
.NotPublic
;
93 if ((mod_flags
& PUBLIC
) != 0)
94 t
|= TypeAttributes
.NestedPublic
;
95 if ((mod_flags
& PRIVATE
) != 0)
96 t
|= TypeAttributes
.NestedPrivate
;
97 if ((mod_flags
& PROTECTED
) != 0 && (mod_flags
& INTERNAL
) != 0)
98 t
|= TypeAttributes
.NestedFamORAssem
;
99 if ((mod_flags
& PROTECTED
) != 0)
100 t
|= TypeAttributes
.NestedFamily
;
101 if ((mod_flags
& INTERNAL
) != 0)
102 t
|= TypeAttributes
.NestedAssembly
;
105 if ((mod_flags
& SEALED
) != 0)
106 t
|= TypeAttributes
.Sealed
;
107 if ((mod_flags
& ABSTRACT
) != 0)
108 t
|= TypeAttributes
.Abstract
;
113 public static TypeAttributes
TypeAttr (int mod_flags
, TypeContainer caller
)
115 TypeAttributes t
= TypeAttr (mod_flags
, caller
.IsTopLevel
);
117 // If we do not have static constructors, static methods
118 // can be invoked without initializing the type.
119 if (!caller
.UserDefinedStaticConstructor
&&
120 (caller
.Kind
!= Kind
.Interface
))
121 t
|= TypeAttributes
.BeforeFieldInit
;
126 public static FieldAttributes
FieldAttr (int mod_flags
)
128 FieldAttributes fa
= 0;
130 if ((mod_flags
& PUBLIC
) != 0)
131 fa
|= FieldAttributes
.Public
;
132 if ((mod_flags
& PRIVATE
) != 0)
133 fa
|= FieldAttributes
.Private
;
134 if ((mod_flags
& PROTECTED
) != 0){
135 if ((mod_flags
& INTERNAL
) != 0)
136 fa
|= FieldAttributes
.FamORAssem
;
138 fa
|= FieldAttributes
.Family
;
140 if ((mod_flags
& INTERNAL
) != 0)
141 fa
|= FieldAttributes
.Assembly
;
144 if ((mod_flags
& STATIC
) != 0)
145 fa
|= FieldAttributes
.Static
;
146 if ((mod_flags
& READONLY
) != 0)
147 fa
|= FieldAttributes
.InitOnly
;
152 public static MethodAttributes
MethodAttr (int mod_flags
)
154 MethodAttributes ma
= MethodAttributes
.HideBySig
;
156 if ((mod_flags
& PUBLIC
) != 0)
157 ma
|= MethodAttributes
.Public
;
158 if ((mod_flags
& PRIVATE
) != 0)
159 ma
|= MethodAttributes
.Private
;
160 if ((mod_flags
& PROTECTED
) != 0){
161 if ((mod_flags
& INTERNAL
) != 0)
162 ma
|= MethodAttributes
.FamORAssem
;
164 ma
|= MethodAttributes
.Family
;
166 if ((mod_flags
& INTERNAL
) != 0)
167 ma
|= MethodAttributes
.Assembly
;
170 if ((mod_flags
& STATIC
) != 0)
171 ma
|= MethodAttributes
.Static
;
172 if ((mod_flags
& ABSTRACT
) != 0){
173 ma
|= MethodAttributes
.Abstract
| MethodAttributes
.Virtual
;
175 if ((mod_flags
& SEALED
) != 0)
176 ma
|= MethodAttributes
.Final
;
178 if ((mod_flags
& VIRTUAL
) != 0)
179 ma
|= MethodAttributes
.Virtual
;
181 if ((mod_flags
& OVERRIDE
) != 0)
182 ma
|= MethodAttributes
.Virtual
;
184 if ((ma
& MethodAttributes
.Virtual
) != 0)
185 ma
|= MethodAttributes
.NewSlot
;
192 // Checks the object @mod modifiers to be in @allowed.
193 // Returns the new mask. Side effect: reports any
194 // incorrect attributes.
196 public static int Check (int allowed
, int mod
, int def_access
, Location l
)
198 int invalid_flags
= (~allowed
) & mod
;
201 if (invalid_flags
== 0){
204 if ((mod
& Modifiers
.UNSAFE
) != 0){
205 if (!RootContext
.Unsafe
){
206 Report
.Error (227, l
,
207 "Unsafe code requires the -unsafe command " +
208 "line option to be specified");
213 // If no accessibility bits provided
214 // then provide the defaults.
216 if ((mod
& Accessibility
) == 0){
222 // Make sure that no conflicting accessibility
223 // bits have been set. Protected+Internal is
224 // allowed, that is why they are placed on bits
225 // 1 and 4 (so the shift 3 basically merges them)
229 a
= ((a
& 2) >> 1) + (a
& 5);
230 a
= ((a
& 4) >> 2) + (a
& 3);
232 Report
.Error (107, l
, "More than one protection modifier specified");
237 for (i
= 1; i
<= TOP
; i
<<= 1){
238 if ((i
& invalid_flags
) == 0)
241 Error_InvalidModifier (l
, Name (i
));
244 return allowed
& mod
;
247 public static void Error_InvalidModifier (Location l
, string name
)
249 Report
.Error (106, l
, "the modifier " + name
+ " is not valid for this item");