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);