Wrap always_inline and noinline attributes in compiler checks and use MSVC equivalent.
[mono.git] / mcs / class / IKVM.Reflection / Reader / GenericTypeParameter.cs
1 /*
2   Copyright (C) 2009-2012 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Text;
27 using IKVM.Reflection.Metadata;
28
29 namespace IKVM.Reflection.Reader
30 {
31         abstract class TypeParameterType : Type
32         {
33                 public sealed override string AssemblyQualifiedName
34                 {
35                         get { return null; }
36                 }
37
38                 public sealed override bool IsValueType
39                 {
40                         get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
41                 }
42
43                 public sealed override Type BaseType
44                 {
45                         get
46                         {
47                                 foreach (Type type in GetGenericParameterConstraints())
48                                 {
49                                         if (!type.IsInterface && !type.IsGenericParameter)
50                                         {
51                                                 return type;
52                                         }
53                                 }
54                                 return this.IsValueType ? this.Module.universe.System_ValueType : this.Module.universe.System_Object;
55                         }
56                 }
57
58                 public override Type[] __GetDeclaredInterfaces()
59                 {
60                         List<Type> list = new List<Type>();
61                         foreach (Type type in GetGenericParameterConstraints())
62                         {
63                                 if (type.IsInterface)
64                                 {
65                                         list.Add(type);
66                                 }
67                         }
68                         return list.ToArray();
69                 }
70
71                 public sealed override TypeAttributes Attributes
72                 {
73                         get { return TypeAttributes.Public; }
74                 }
75
76                 public sealed override string FullName
77                 {
78                         get { return null; }
79                 }
80
81                 public sealed override string ToString()
82                 {
83                         return this.Name;
84                 }
85
86                 public sealed override bool IsGenericParameter
87                 {
88                         get { return true; }
89                 }
90
91                 public sealed override bool __ContainsMissingType
92                 {
93                         get
94                         {
95                                 bool freeList = false;
96                                 try
97                                 {
98                                         foreach (Type type in GetGenericParameterConstraints())
99                                         {
100                                                 if (type.__IsMissing)
101                                                 {
102                                                         return true;
103                                                 }
104                                                 else if (type.IsConstructedGenericType || type.HasElementType || type.__IsFunctionPointer)
105                                                 {
106                                                         // if a constructed type contains generic parameters,
107                                                         // it might contain this type parameter again and
108                                                         // to prevent infinite recurssion, we keep a thread local
109                                                         // list of type parameters we've already processed
110                                                         if (type.ContainsGenericParameters)
111                                                         {
112                                                                 if (containsMissingTypeHack == null)
113                                                                 {
114                                                                         freeList = true;
115                                                                         containsMissingTypeHack = new List<Type>();
116                                                                 }
117                                                                 else if (containsMissingTypeHack.Contains(this))
118                                                                 {
119                                                                         return false;
120                                                                 }
121                                                                 containsMissingTypeHack.Add(this);
122                                                         }
123                                                         if (type.__ContainsMissingType)
124                                                         {
125                                                                 return true;
126                                                         }
127                                                 }
128                                         }
129                                         return false;
130                                 }
131                                 finally
132                                 {
133                                         if (freeList)
134                                         {
135                                                 containsMissingTypeHack = null;
136                                         }
137                                 }
138                         }
139                 }
140
141                 [ThreadStatic]
142                 private static List<Type> containsMissingTypeHack;
143         }
144
145         sealed class UnboundGenericMethodParameter : TypeParameterType
146         {
147                 private static readonly DummyModule module = new DummyModule();
148                 private readonly int position;
149
150                 private sealed class DummyModule : NonPEModule
151                 {
152                         internal DummyModule()
153                                 : base(new Universe())
154                         {
155                         }
156
157                         protected override Exception NotSupportedException()
158                         {
159                                 return new InvalidOperationException();
160                         }
161
162                         protected override Exception ArgumentOutOfRangeException()
163                         {
164                                 return new InvalidOperationException();
165                         }
166
167                         public override bool Equals(object obj)
168                         {
169                                 throw new InvalidOperationException();
170                         }
171
172                         public override int GetHashCode()
173                         {
174                                 throw new InvalidOperationException();
175                         }
176
177                         public override string ToString()
178                         {
179                                 throw new InvalidOperationException();
180                         }
181
182                         public override int MDStreamVersion
183                         {
184                                 get { throw new InvalidOperationException(); }
185                         }
186
187                         public override Assembly Assembly
188                         {
189                                 get { throw new InvalidOperationException(); }
190                         }
191
192                         internal override Type FindType(TypeName typeName)
193                         {
194                                 throw new InvalidOperationException();
195                         }
196
197                         internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
198                         {
199                                 throw new InvalidOperationException();
200                         }
201
202                         internal override void GetTypesImpl(List<Type> list)
203                         {
204                                 throw new InvalidOperationException();
205                         }
206
207                         public override string FullyQualifiedName
208                         {
209                                 get { throw new InvalidOperationException(); }
210                         }
211
212                         public override string Name
213                         {
214                                 get { throw new InvalidOperationException(); }
215                         }
216
217                         public override Guid ModuleVersionId
218                         {
219                                 get { throw new InvalidOperationException(); }
220                         }
221
222                         public override string ScopeName
223                         {
224                                 get { throw new InvalidOperationException(); }
225                         }
226                 }
227
228                 internal static Type Make(int position)
229                 {
230                         return module.universe.CanonicalizeType(new UnboundGenericMethodParameter(position));
231                 }
232
233                 private UnboundGenericMethodParameter(int position)
234                 {
235                         this.position = position;
236                 }
237
238                 public override bool Equals(object obj)
239                 {
240                         UnboundGenericMethodParameter other = obj as UnboundGenericMethodParameter;
241                         return other != null && other.position == position;
242                 }
243
244                 public override int GetHashCode()
245                 {
246                         return position;
247                 }
248
249                 public override string Namespace
250                 {
251                         get { throw new InvalidOperationException(); }
252                 }
253
254                 public override string Name
255                 {
256                         get { throw new InvalidOperationException(); }
257                 }
258
259                 public override int MetadataToken
260                 {
261                         get { throw new InvalidOperationException(); }
262                 }
263
264                 public override Module Module
265                 {
266                         get { return module; }
267                 }
268
269                 public override int GenericParameterPosition
270                 {
271                         get { return position; }
272                 }
273
274                 public override Type DeclaringType
275                 {
276                         get { return null; }
277                 }
278
279                 public override MethodBase DeclaringMethod
280                 {
281                         get { throw new InvalidOperationException(); }
282                 }
283
284                 public override Type[] GetGenericParameterConstraints()
285                 {
286                         throw new InvalidOperationException();
287                 }
288
289                 public override GenericParameterAttributes GenericParameterAttributes
290                 {
291                         get { throw new InvalidOperationException(); }
292                 }
293
294                 internal override Type BindTypeParameters(IGenericBinder binder)
295                 {
296                         return binder.BindMethodParameter(this);
297                 }
298
299                 internal override bool IsBaked
300                 {
301                         get { throw new InvalidOperationException(); }
302                 }
303         }
304
305         sealed class GenericTypeParameter : TypeParameterType
306         {
307                 private readonly ModuleReader module;
308                 private readonly int index;
309
310                 internal GenericTypeParameter(ModuleReader module, int index)
311                 {
312                         this.module = module;
313                         this.index = index;
314                 }
315
316                 public override bool Equals(object obj)
317                 {
318                         return base.Equals(obj);
319                 }
320
321                 public override int GetHashCode()
322                 {
323                         return base.GetHashCode();
324                 }
325
326                 public override string Namespace
327                 {
328                         get { return DeclaringType.Namespace; }
329                 }
330
331                 public override string Name
332                 {
333                         get { return module.GetString(module.GenericParam.records[index].Name); }
334                 }
335
336                 public override Module Module
337                 {
338                         get { return module; }
339                 }
340
341                 public override int MetadataToken
342                 {
343                         get { return (GenericParamTable.Index << 24) + index + 1; }
344                 }
345
346                 public override int GenericParameterPosition
347                 {
348                         get { return module.GenericParam.records[index].Number; }
349                 }
350
351                 public override Type DeclaringType
352                 {
353                         get
354                         {
355                                 int owner = module.GenericParam.records[index].Owner;
356                                 return (owner >> 24) == TypeDefTable.Index ? module.ResolveType(owner) : null;
357                         }
358                 }
359
360                 public override MethodBase DeclaringMethod
361                 {
362                         get
363                         {
364                                 int owner = module.GenericParam.records[index].Owner;
365                                 return (owner >> 24) == MethodDefTable.Index ? module.ResolveMethod(owner) : null;
366                         }
367                 }
368
369                 public override Type[] GetGenericParameterConstraints()
370                 {
371                         IGenericContext context = (this.DeclaringMethod as IGenericContext) ?? this.DeclaringType;
372                         List<Type> list = new List<Type>();
373                         foreach (int i in module.GenericParamConstraint.Filter(this.MetadataToken))
374                         {
375                                 list.Add(module.ResolveType(module.GenericParamConstraint.records[i].Constraint, context));
376                         }
377                         return list.ToArray();
378                 }
379
380                 public override GenericParameterAttributes GenericParameterAttributes
381                 {
382                         get { return (GenericParameterAttributes)module.GenericParam.records[index].Flags; }
383                 }
384
385                 internal override Type BindTypeParameters(IGenericBinder binder)
386                 {
387                         int owner = module.GenericParam.records[index].Owner;
388                         if ((owner >> 24) == MethodDefTable.Index)
389                         {
390                                 return binder.BindMethodParameter(this);
391                         }
392                         else
393                         {
394                                 return binder.BindTypeParameter(this);
395                         }
396                 }
397
398                 internal override bool IsBaked
399                 {
400                         get { return true; }
401                 }
402         }
403 }