2 // modifiers.cs: Modifier handling.
5 using System
.Reflection
;
13 // The ordering of the following 4 constants
14 // has been carefully done.
33 // Compiler specific flags
35 PROPERTY_CUSTOM
= 0x4000,
36 OVERRIDE_UNCHECKED
= 0x8000,
38 DEFAULT_ACCESS_MODIFER
= 0x40000,
39 METHOD_EXTENSION
= 0x80000,
40 COMPILER_GENERATED
= 0x100000,
41 BACKING_FIELD
= 0x200000,
42 DEBUGGER_HIDDEN
= 0x400000,
44 AccessibilityMask
= PUBLIC
| PROTECTED
| INTERNAL
| PRIVATE
,
45 AllowedExplicitImplFlags
= UNSAFE
| EXTERN
,
48 static class ModifiersExtensions
50 public static string AccessibilityName (Modifiers mod
)
52 switch (mod
& Modifiers
.AccessibilityMask
) {
53 case Modifiers
.PUBLIC
:
55 case Modifiers
.PROTECTED
:
57 case Modifiers
.PROTECTED
| Modifiers
.INTERNAL
:
58 return "protected internal";
59 case Modifiers
.INTERNAL
:
61 case Modifiers
.PRIVATE
:
64 throw new NotImplementedException (mod
.ToString ());
68 static public string Name (Modifiers i
)
75 case Modifiers
.PUBLIC
:
77 case Modifiers
.PROTECTED
:
78 s
= "protected"; break;
79 case Modifiers
.INTERNAL
:
80 s
= "internal"; break;
81 case Modifiers
.PRIVATE
:
83 case Modifiers
.ABSTRACT
:
84 s
= "abstract"; break;
85 case Modifiers
.SEALED
:
87 case Modifiers
.STATIC
:
89 case Modifiers
.READONLY
:
90 s
= "readonly"; break;
91 case Modifiers
.VIRTUAL
:
93 case Modifiers
.OVERRIDE
:
94 s
= "override"; break;
95 case Modifiers
.EXTERN
:
97 case Modifiers
.VOLATILE
:
98 s
= "volatile"; break;
99 case Modifiers
.UNSAFE
:
107 // Used by custom property accessors to check whether @modA is more restrictive than @modB
109 public static bool IsRestrictedModifier (Modifiers modA
, Modifiers modB
)
113 if ((modB
& Modifiers
.PUBLIC
) != 0) {
114 flags
= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
115 } else if ((modB
& Modifiers
.PROTECTED
) != 0) {
116 if ((modB
& Modifiers
.INTERNAL
) != 0)
117 flags
= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
119 flags
|= Modifiers
.PRIVATE
;
120 } else if ((modB
& Modifiers
.INTERNAL
) != 0)
121 flags
= Modifiers
.PRIVATE
;
123 return modB
!= modA
&& (modA
& (~flags
)) == 0;
126 public static TypeAttributes
TypeAttr (Modifiers mod_flags
, bool is_toplevel
)
128 TypeAttributes t
= 0;
131 if ((mod_flags
& Modifiers
.PUBLIC
) != 0)
132 t
= TypeAttributes
.Public
;
133 else if ((mod_flags
& Modifiers
.PRIVATE
) != 0)
134 t
= TypeAttributes
.NotPublic
;
136 if ((mod_flags
& Modifiers
.PUBLIC
) != 0)
137 t
= TypeAttributes
.NestedPublic
;
138 else if ((mod_flags
& Modifiers
.PRIVATE
) != 0)
139 t
= TypeAttributes
.NestedPrivate
;
140 else if ((mod_flags
& (Modifiers
.PROTECTED
| Modifiers
.INTERNAL
)) == (Modifiers
.PROTECTED
| Modifiers
.INTERNAL
))
141 t
= TypeAttributes
.NestedFamORAssem
;
142 else if ((mod_flags
& Modifiers
.PROTECTED
) != 0)
143 t
= TypeAttributes
.NestedFamily
;
144 else if ((mod_flags
& Modifiers
.INTERNAL
) != 0)
145 t
= TypeAttributes
.NestedAssembly
;
148 if ((mod_flags
& Modifiers
.SEALED
) != 0)
149 t
|= TypeAttributes
.Sealed
;
150 if ((mod_flags
& Modifiers
.ABSTRACT
) != 0)
151 t
|= TypeAttributes
.Abstract
;
156 public static FieldAttributes
FieldAttr (Modifiers mod_flags
)
158 FieldAttributes fa
= 0;
160 if ((mod_flags
& Modifiers
.PUBLIC
) != 0)
161 fa
|= FieldAttributes
.Public
;
162 if ((mod_flags
& Modifiers
.PRIVATE
) != 0)
163 fa
|= FieldAttributes
.Private
;
164 if ((mod_flags
& Modifiers
.PROTECTED
) != 0) {
165 if ((mod_flags
& Modifiers
.INTERNAL
) != 0)
166 fa
|= FieldAttributes
.FamORAssem
;
168 fa
|= FieldAttributes
.Family
;
170 if ((mod_flags
& Modifiers
.INTERNAL
) != 0)
171 fa
|= FieldAttributes
.Assembly
;
174 if ((mod_flags
& Modifiers
.STATIC
) != 0)
175 fa
|= FieldAttributes
.Static
;
176 if ((mod_flags
& Modifiers
.READONLY
) != 0)
177 fa
|= FieldAttributes
.InitOnly
;
182 public static MethodAttributes
MethodAttr (Modifiers mod_flags
)
184 MethodAttributes ma
= MethodAttributes
.HideBySig
;
186 switch (mod_flags
& Modifiers
.AccessibilityMask
) {
187 case Modifiers
.PUBLIC
:
188 ma
|= MethodAttributes
.Public
;
190 case Modifiers
.PRIVATE
:
191 ma
|= MethodAttributes
.Private
;
193 case Modifiers
.PROTECTED
| Modifiers
.INTERNAL
:
194 ma
|= MethodAttributes
.FamORAssem
;
196 case Modifiers
.PROTECTED
:
197 ma
|= MethodAttributes
.Family
;
199 case Modifiers
.INTERNAL
:
200 ma
|= MethodAttributes
.Assembly
;
203 throw new NotImplementedException (mod_flags
.ToString ());
206 if ((mod_flags
& Modifiers
.STATIC
) != 0)
207 ma
|= MethodAttributes
.Static
;
208 if ((mod_flags
& Modifiers
.ABSTRACT
) != 0) {
209 ma
|= MethodAttributes
.Abstract
| MethodAttributes
.Virtual
;
211 if ((mod_flags
& Modifiers
.SEALED
) != 0)
212 ma
|= MethodAttributes
.Final
;
214 if ((mod_flags
& Modifiers
.VIRTUAL
) != 0)
215 ma
|= MethodAttributes
.Virtual
;
217 if ((mod_flags
& Modifiers
.OVERRIDE
) != 0) {
218 ma
|= MethodAttributes
.Virtual
;
220 if ((ma
& MethodAttributes
.Virtual
) != 0)
221 ma
|= MethodAttributes
.NewSlot
;
228 // Checks the object @mod modifiers to be in @allowed.
229 // Returns the new mask. Side effect: reports any
230 // incorrect attributes.
232 public static Modifiers
Check (Modifiers allowed
, Modifiers mod
, Modifiers def_access
, Location l
, Report Report
)
234 int invalid_flags
= (~
(int) allowed
) & ((int) mod
& ((int) Modifiers
.TOP
- 1));
237 if (invalid_flags
== 0){
239 if ((mod
& Modifiers
.UNSAFE
) != 0){
240 RootContext
.CheckUnsafeOption (l
, Report
);
244 // If no accessibility bits provided
245 // then provide the defaults.
247 if ((mod
& Modifiers
.AccessibilityMask
) == 0) {
250 mod
|= Modifiers
.DEFAULT_ACCESS_MODIFER
;
255 // Make sure that no conflicting accessibility
256 // bits have been set. Protected+Internal is
257 // allowed, that is why they are placed on bits
258 // 1 and 4 (so the shift 3 basically merges them)
263 a
= ((a
& 2) >> 1) + (a
& 5);
264 a
= ((a
& 4) >> 2) + (a
& 3);
266 Report
.Error (107, l
, "More than one protection modifier specified");
271 for (i
= 1; i
<= (int) Modifiers
.TOP
; i
<<= 1) {
272 if ((i
& invalid_flags
) == 0)
275 Error_InvalidModifier (l
, Name ((Modifiers
) i
), Report
);
278 return allowed
& mod
;
281 public static void Error_InvalidModifier (Location l
, string name
, Report Report
)
283 Report
.Error (106, l
, "The modifier `{0}' is not valid for this item", name
);