PageRenderTime 65ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs

http://github.com/icsharpcode/ILSpy
C# | 2496 lines | 2030 code | 358 blank | 108 comment | 389 complexity | 8d98d5b9f24e6fb154dec2af4eab76ca MD5 | raw file
Possible License(s): LGPL-2.1, MIT, CC-BY-SA-3.0
  1. //
  2. // constant.cs: Constants.
  3. //
  4. // Author:
  5. // Miguel de Icaza (miguel@ximian.com)
  6. // Marek Safar (marek.safar@gmail.com)
  7. //
  8. // Copyright 2001-2003 Ximian, Inc.
  9. // Copyright 2003-2008 Novell, Inc.
  10. // Copyright 2011-2013 Xamarin Inc
  11. //
  12. using System;
  13. using System.Globalization;
  14. #if STATIC
  15. using IKVM.Reflection.Emit;
  16. #else
  17. using System.Reflection.Emit;
  18. #endif
  19. namespace Mono.CSharp {
  20. /// <summary>
  21. /// Base class for constants and literals.
  22. /// </summary>
  23. public abstract class Constant : Expression
  24. {
  25. static readonly NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
  26. protected Constant (Location loc)
  27. {
  28. this.loc = loc;
  29. }
  30. override public string ToString ()
  31. {
  32. return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
  33. }
  34. /// <summary>
  35. /// This is used to obtain the actual value of the literal
  36. /// cast into an object.
  37. /// </summary>
  38. public abstract object GetValue ();
  39. public abstract long GetValueAsLong ();
  40. public abstract string GetValueAsLiteral ();
  41. #if !STATIC
  42. //
  43. // Returns an object value which is typed to contant type
  44. //
  45. public virtual object GetTypedValue ()
  46. {
  47. return GetValue ();
  48. }
  49. #endif
  50. public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
  51. {
  52. if (!expl && IsLiteral &&
  53. BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
  54. BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
  55. ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
  56. GetValueAsLiteral (), target.GetSignatureForError ());
  57. } else {
  58. base.Error_ValueCannotBeConverted (ec, target, expl);
  59. }
  60. }
  61. public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type)
  62. {
  63. Constant c = ConvertImplicitly (type);
  64. if (c == null)
  65. Error_ValueCannotBeConverted (ec, type, false);
  66. return c;
  67. }
  68. public override bool ContainsEmitWithAwait ()
  69. {
  70. return false;
  71. }
  72. public virtual Constant ConvertImplicitly (TypeSpec type)
  73. {
  74. if (this.type == type)
  75. return this;
  76. if (!Convert.ImplicitNumericConversionExists (this.type, type))
  77. return null;
  78. bool fail;
  79. object constant_value = ChangeType (GetValue (), type, out fail);
  80. if (fail){
  81. //
  82. // We should always catch the error before this is ever
  83. // reached, by calling Convert.ImplicitStandardConversionExists
  84. //
  85. throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
  86. Type.GetSignatureForError (), type.GetSignatureForError ());
  87. }
  88. return CreateConstantFromValue (type, constant_value, loc);
  89. }
  90. //
  91. // Returns a constant instance based on Type
  92. //
  93. public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
  94. {
  95. switch (t.BuiltinType) {
  96. case BuiltinTypeSpec.Type.Int:
  97. return new IntConstant (t, (int) v, loc);
  98. case BuiltinTypeSpec.Type.String:
  99. return new StringConstant (t, (string) v, loc);
  100. case BuiltinTypeSpec.Type.UInt:
  101. return new UIntConstant (t, (uint) v, loc);
  102. case BuiltinTypeSpec.Type.Long:
  103. return new LongConstant (t, (long) v, loc);
  104. case BuiltinTypeSpec.Type.ULong:
  105. return new ULongConstant (t, (ulong) v, loc);
  106. case BuiltinTypeSpec.Type.Float:
  107. return new FloatConstant (t, (float) v, loc);
  108. case BuiltinTypeSpec.Type.Double:
  109. return new DoubleConstant (t, (double) v, loc);
  110. case BuiltinTypeSpec.Type.Short:
  111. return new ShortConstant (t, (short) v, loc);
  112. case BuiltinTypeSpec.Type.UShort:
  113. return new UShortConstant (t, (ushort) v, loc);
  114. case BuiltinTypeSpec.Type.SByte:
  115. return new SByteConstant (t, (sbyte) v, loc);
  116. case BuiltinTypeSpec.Type.Byte:
  117. return new ByteConstant (t, (byte) v, loc);
  118. case BuiltinTypeSpec.Type.Char:
  119. return new CharConstant (t, (char) v, loc);
  120. case BuiltinTypeSpec.Type.Bool:
  121. return new BoolConstant (t, (bool) v, loc);
  122. case BuiltinTypeSpec.Type.Decimal:
  123. return new DecimalConstant (t, (decimal) v, loc);
  124. }
  125. if (t.IsEnum) {
  126. var real_type = EnumSpec.GetUnderlyingType (t);
  127. return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
  128. }
  129. if (v == null) {
  130. if (t.IsNullableType)
  131. return Nullable.LiftedNull.Create (t, loc);
  132. if (TypeSpec.IsReferenceType (t))
  133. return new NullConstant (t, loc);
  134. }
  135. #if STATIC
  136. throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
  137. #else
  138. return null;
  139. #endif
  140. }
  141. //
  142. // Returns a constant instance based on value and type. This is probing version of
  143. // CreateConstantFromValue
  144. //
  145. public static Constant ExtractConstantFromValue (TypeSpec t, object v, Location loc)
  146. {
  147. switch (t.BuiltinType) {
  148. case BuiltinTypeSpec.Type.Int:
  149. if (v is int)
  150. return new IntConstant (t, (int) v, loc);
  151. break;
  152. case BuiltinTypeSpec.Type.String:
  153. if (v is string)
  154. return new StringConstant (t, (string) v, loc);
  155. break;
  156. case BuiltinTypeSpec.Type.UInt:
  157. if (v is uint)
  158. return new UIntConstant (t, (uint) v, loc);
  159. break;
  160. case BuiltinTypeSpec.Type.Long:
  161. if (v is long)
  162. return new LongConstant (t, (long) v, loc);
  163. break;
  164. case BuiltinTypeSpec.Type.ULong:
  165. if (v is ulong)
  166. return new ULongConstant (t, (ulong) v, loc);
  167. break;
  168. case BuiltinTypeSpec.Type.Float:
  169. if (v is float)
  170. return new FloatConstant (t, (float) v, loc);
  171. break;
  172. case BuiltinTypeSpec.Type.Double:
  173. if (v is double)
  174. return new DoubleConstant (t, (double) v, loc);
  175. break;
  176. case BuiltinTypeSpec.Type.Short:
  177. if (v is short)
  178. return new ShortConstant (t, (short) v, loc);
  179. break;
  180. case BuiltinTypeSpec.Type.UShort:
  181. if (v is ushort)
  182. return new UShortConstant (t, (ushort) v, loc);
  183. break;
  184. case BuiltinTypeSpec.Type.SByte:
  185. if (v is sbyte)
  186. return new SByteConstant (t, (sbyte) v, loc);
  187. break;
  188. case BuiltinTypeSpec.Type.Byte:
  189. if (v is byte)
  190. return new ByteConstant (t, (byte) v, loc);
  191. break;
  192. case BuiltinTypeSpec.Type.Char:
  193. if (v is char)
  194. return new CharConstant (t, (char) v, loc);
  195. break;
  196. case BuiltinTypeSpec.Type.Bool:
  197. if (v is bool)
  198. return new BoolConstant (t, (bool) v, loc);
  199. break;
  200. case BuiltinTypeSpec.Type.Decimal:
  201. if (v is decimal)
  202. return new DecimalConstant (t, (decimal) v, loc);
  203. break;
  204. }
  205. if (t.IsEnum) {
  206. var real_type = EnumSpec.GetUnderlyingType (t);
  207. return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
  208. }
  209. if (v == null) {
  210. if (t.IsNullableType)
  211. return Nullable.LiftedNull.Create (t, loc);
  212. if (TypeSpec.IsReferenceType (t))
  213. return new NullConstant (t, loc);
  214. }
  215. return null;
  216. }
  217. public override Expression CreateExpressionTree (ResolveContext ec)
  218. {
  219. Arguments args = new Arguments (2);
  220. args.Add (new Argument (this));
  221. args.Add (new Argument (new TypeOf (type, loc)));
  222. return CreateExpressionFactoryCall (ec, "Constant", args);
  223. }
  224. /// <summary>
  225. /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
  226. /// It throws OverflowException
  227. /// </summary>
  228. // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
  229. public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
  230. // This is a custom version of Convert.ChangeType() which works
  231. // with the TypeBuilder defined types when compiling corlib.
  232. static object ChangeType (object value, TypeSpec targetType, out bool error)
  233. {
  234. IConvertible convert_value = value as IConvertible;
  235. if (convert_value == null) {
  236. error = true;
  237. return null;
  238. }
  239. //
  240. // We cannot rely on build-in type conversions as they are
  241. // more limited than what C# supports.
  242. // See char -> float/decimal/double conversion
  243. //
  244. error = false;
  245. try {
  246. switch (targetType.BuiltinType) {
  247. case BuiltinTypeSpec.Type.Bool:
  248. return convert_value.ToBoolean (nfi);
  249. case BuiltinTypeSpec.Type.Byte:
  250. return convert_value.ToByte (nfi);
  251. case BuiltinTypeSpec.Type.Char:
  252. return convert_value.ToChar (nfi);
  253. case BuiltinTypeSpec.Type.Short:
  254. return convert_value.ToInt16 (nfi);
  255. case BuiltinTypeSpec.Type.Int:
  256. return convert_value.ToInt32 (nfi);
  257. case BuiltinTypeSpec.Type.Long:
  258. return convert_value.ToInt64 (nfi);
  259. case BuiltinTypeSpec.Type.SByte:
  260. return convert_value.ToSByte (nfi);
  261. case BuiltinTypeSpec.Type.Decimal:
  262. if (convert_value.GetType () == typeof (char))
  263. return (decimal) convert_value.ToInt32 (nfi);
  264. return convert_value.ToDecimal (nfi);
  265. case BuiltinTypeSpec.Type.Double:
  266. if (convert_value.GetType () == typeof (char))
  267. return (double) convert_value.ToInt32 (nfi);
  268. return convert_value.ToDouble (nfi);
  269. case BuiltinTypeSpec.Type.Float:
  270. if (convert_value.GetType () == typeof (char))
  271. return (float) convert_value.ToInt32 (nfi);
  272. return convert_value.ToSingle (nfi);
  273. case BuiltinTypeSpec.Type.String:
  274. return convert_value.ToString (nfi);
  275. case BuiltinTypeSpec.Type.UShort:
  276. return convert_value.ToUInt16 (nfi);
  277. case BuiltinTypeSpec.Type.UInt:
  278. return convert_value.ToUInt32 (nfi);
  279. case BuiltinTypeSpec.Type.ULong:
  280. return convert_value.ToUInt64 (nfi);
  281. case BuiltinTypeSpec.Type.Object:
  282. return value;
  283. }
  284. } catch {
  285. }
  286. error = true;
  287. return null;
  288. }
  289. protected override Expression DoResolve (ResolveContext rc)
  290. {
  291. return this;
  292. }
  293. //
  294. // Attempts to do a compile-time folding of a constant cast and handles
  295. // error reporting for constant overlows only, on normal conversion
  296. // errors returns null
  297. //
  298. public Constant Reduce (ResolveContext ec, TypeSpec target_type)
  299. {
  300. try {
  301. return TryReduceConstant (ec, target_type);
  302. } catch (OverflowException) {
  303. if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
  304. ec.Report.Error (221, loc,
  305. "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
  306. GetValueAsLiteral (), target_type.GetSignatureForError ());
  307. } else {
  308. Error_ValueCannotBeConverted (ec, target_type, false);
  309. }
  310. return New.Constantify (target_type, loc);
  311. }
  312. }
  313. public Constant TryReduce (ResolveContext rc, TypeSpec targetType)
  314. {
  315. try {
  316. return TryReduceConstant (rc, targetType);
  317. } catch (OverflowException) {
  318. return null;
  319. }
  320. }
  321. Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
  322. {
  323. if (Type == target_type) {
  324. //
  325. // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
  326. //
  327. if (IsLiteral)
  328. return CreateConstantFromValue (target_type, GetValue (), loc);
  329. return this;
  330. }
  331. Constant c;
  332. if (target_type.IsEnum) {
  333. c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
  334. if (c == null)
  335. return null;
  336. return new EnumConstant (c, target_type);
  337. }
  338. return ConvertExplicitly (ec.ConstantCheckState, target_type);
  339. }
  340. /// <summary>
  341. /// Need to pass type as the constant can require a boxing
  342. /// and in such case no optimization is possible
  343. /// </summary>
  344. public bool IsDefaultInitializer (TypeSpec type)
  345. {
  346. if (type == Type)
  347. return IsDefaultValue;
  348. return this is NullLiteral;
  349. }
  350. public abstract bool IsDefaultValue {
  351. get;
  352. }
  353. public abstract bool IsNegative {
  354. get;
  355. }
  356. //
  357. // When constant is declared as literal
  358. //
  359. public virtual bool IsLiteral {
  360. get { return false; }
  361. }
  362. public virtual bool IsOneInteger {
  363. get { return false; }
  364. }
  365. public override bool IsSideEffectFree {
  366. get {
  367. return true;
  368. }
  369. }
  370. //
  371. // Returns true iff 1) the stack type of this is one of Object,
  372. // int32, int64 and 2) this == 0 or this == null.
  373. //
  374. public virtual bool IsZeroInteger {
  375. get { return false; }
  376. }
  377. public override void EmitSideEffect (EmitContext ec)
  378. {
  379. // do nothing
  380. }
  381. public sealed override Expression Clone (CloneContext clonectx)
  382. {
  383. // No cloning is not needed for constants
  384. return this;
  385. }
  386. protected override void CloneTo (CloneContext clonectx, Expression target)
  387. {
  388. throw new NotSupportedException ("should not be reached");
  389. }
  390. public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
  391. {
  392. #if STATIC
  393. return base.MakeExpression (ctx);
  394. #else
  395. return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
  396. #endif
  397. }
  398. public new bool Resolve (ResolveContext rc)
  399. {
  400. // It exists only as hint not to call Resolve on constants
  401. return true;
  402. }
  403. public override object Accept (StructuralVisitor visitor)
  404. {
  405. return visitor.Visit (this);
  406. }
  407. }
  408. public abstract class IntegralConstant : Constant
  409. {
  410. protected IntegralConstant (TypeSpec type, Location loc)
  411. : base (loc)
  412. {
  413. this.type = type;
  414. eclass = ExprClass.Value;
  415. }
  416. public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
  417. {
  418. try {
  419. ConvertExplicitly (true, target);
  420. base.Error_ValueCannotBeConverted (ec, target, expl);
  421. }
  422. catch
  423. {
  424. ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
  425. GetValue ().ToString (), target.GetSignatureForError ());
  426. }
  427. }
  428. public override string GetValueAsLiteral ()
  429. {
  430. return GetValue ().ToString ();
  431. }
  432. public abstract Constant Increment ();
  433. }
  434. public class BoolConstant : Constant {
  435. public readonly bool Value;
  436. public BoolConstant (BuiltinTypes types, bool val, Location loc)
  437. : this (types.Bool, val, loc)
  438. {
  439. }
  440. public BoolConstant (TypeSpec type, bool val, Location loc)
  441. : base (loc)
  442. {
  443. eclass = ExprClass.Value;
  444. this.type = type;
  445. Value = val;
  446. }
  447. public override object GetValue ()
  448. {
  449. return (object) Value;
  450. }
  451. public override string GetValueAsLiteral ()
  452. {
  453. return Value ? "true" : "false";
  454. }
  455. public override long GetValueAsLong ()
  456. {
  457. return Value ? 1 : 0;
  458. }
  459. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  460. {
  461. enc.Encode (Value);
  462. }
  463. public override void Emit (EmitContext ec)
  464. {
  465. if (Value)
  466. ec.EmitInt (1);
  467. else
  468. ec.EmitInt (0);
  469. }
  470. public override bool IsDefaultValue {
  471. get {
  472. return !Value;
  473. }
  474. }
  475. public override bool IsNegative {
  476. get {
  477. return false;
  478. }
  479. }
  480. public override bool IsZeroInteger {
  481. get { return Value == false; }
  482. }
  483. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  484. {
  485. return null;
  486. }
  487. }
  488. public class ByteConstant : IntegralConstant
  489. {
  490. public readonly byte Value;
  491. public ByteConstant (BuiltinTypes types, byte v, Location loc)
  492. : this (types.Byte, v, loc)
  493. {
  494. }
  495. public ByteConstant (TypeSpec type, byte v, Location loc)
  496. : base (type, loc)
  497. {
  498. Value = v;
  499. }
  500. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  501. {
  502. enc.Encode (Value);
  503. }
  504. public override void Emit (EmitContext ec)
  505. {
  506. ec.EmitInt (Value);
  507. }
  508. public override object GetValue ()
  509. {
  510. return Value;
  511. }
  512. public override long GetValueAsLong ()
  513. {
  514. return Value;
  515. }
  516. public override Constant Increment ()
  517. {
  518. return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
  519. }
  520. public override bool IsDefaultValue {
  521. get {
  522. return Value == 0;
  523. }
  524. }
  525. public override bool IsOneInteger {
  526. get {
  527. return Value == 1;
  528. }
  529. }
  530. public override bool IsNegative {
  531. get {
  532. return false;
  533. }
  534. }
  535. public override bool IsZeroInteger {
  536. get { return Value == 0; }
  537. }
  538. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  539. {
  540. switch (target_type.BuiltinType) {
  541. case BuiltinTypeSpec.Type.SByte:
  542. if (in_checked_context){
  543. if (Value > SByte.MaxValue)
  544. throw new OverflowException ();
  545. }
  546. return new SByteConstant (target_type, (sbyte) Value, Location);
  547. case BuiltinTypeSpec.Type.Short:
  548. return new ShortConstant (target_type, (short) Value, Location);
  549. case BuiltinTypeSpec.Type.UShort:
  550. return new UShortConstant (target_type, (ushort) Value, Location);
  551. case BuiltinTypeSpec.Type.Int:
  552. return new IntConstant (target_type, (int) Value, Location);
  553. case BuiltinTypeSpec.Type.UInt:
  554. return new UIntConstant (target_type, (uint) Value, Location);
  555. case BuiltinTypeSpec.Type.Long:
  556. return new LongConstant (target_type, (long) Value, Location);
  557. case BuiltinTypeSpec.Type.ULong:
  558. return new ULongConstant (target_type, (ulong) Value, Location);
  559. case BuiltinTypeSpec.Type.Float:
  560. return new FloatConstant (target_type, (float) Value, Location);
  561. case BuiltinTypeSpec.Type.Double:
  562. return new DoubleConstant (target_type, (double) Value, Location);
  563. case BuiltinTypeSpec.Type.Char:
  564. return new CharConstant (target_type, (char) Value, Location);
  565. case BuiltinTypeSpec.Type.Decimal:
  566. return new DecimalConstant (target_type, (decimal) Value, Location);
  567. }
  568. return null;
  569. }
  570. }
  571. public class CharConstant : Constant {
  572. public readonly char Value;
  573. public CharConstant (BuiltinTypes types, char v, Location loc)
  574. : this (types.Char, v, loc)
  575. {
  576. }
  577. public CharConstant (TypeSpec type, char v, Location loc)
  578. : base (loc)
  579. {
  580. this.type = type;
  581. eclass = ExprClass.Value;
  582. Value = v;
  583. }
  584. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  585. {
  586. enc.Encode ((ushort) Value);
  587. }
  588. public override void Emit (EmitContext ec)
  589. {
  590. ec.EmitInt (Value);
  591. }
  592. static string descape (char c)
  593. {
  594. switch (c){
  595. case '\a':
  596. return "\\a";
  597. case '\b':
  598. return "\\b";
  599. case '\n':
  600. return "\\n";
  601. case '\t':
  602. return "\\t";
  603. case '\v':
  604. return "\\v";
  605. case '\r':
  606. return "\\r";
  607. case '\\':
  608. return "\\\\";
  609. case '\f':
  610. return "\\f";
  611. case '\0':
  612. return "\\0";
  613. case '"':
  614. return "\\\"";
  615. case '\'':
  616. return "\\\'";
  617. }
  618. return c.ToString ();
  619. }
  620. public override object GetValue ()
  621. {
  622. return Value;
  623. }
  624. public override long GetValueAsLong ()
  625. {
  626. return Value;
  627. }
  628. public override string GetValueAsLiteral ()
  629. {
  630. return "\"" + descape (Value) + "\"";
  631. }
  632. public override bool IsDefaultValue {
  633. get {
  634. return Value == 0;
  635. }
  636. }
  637. public override bool IsNegative {
  638. get {
  639. return false;
  640. }
  641. }
  642. public override bool IsZeroInteger {
  643. get { return Value == '\0'; }
  644. }
  645. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  646. {
  647. switch (target_type.BuiltinType) {
  648. case BuiltinTypeSpec.Type.Byte:
  649. if (in_checked_context) {
  650. if (Value < Byte.MinValue || Value > Byte.MaxValue)
  651. throw new OverflowException ();
  652. }
  653. return new ByteConstant (target_type, (byte) Value, Location);
  654. case BuiltinTypeSpec.Type.SByte:
  655. if (in_checked_context) {
  656. if (Value > SByte.MaxValue)
  657. throw new OverflowException ();
  658. }
  659. return new SByteConstant (target_type, (sbyte) Value, Location);
  660. case BuiltinTypeSpec.Type.Short:
  661. if (in_checked_context) {
  662. if (Value > Int16.MaxValue)
  663. throw new OverflowException ();
  664. }
  665. return new ShortConstant (target_type, (short) Value, Location);
  666. case BuiltinTypeSpec.Type.Int:
  667. return new IntConstant (target_type, (int) Value, Location);
  668. case BuiltinTypeSpec.Type.UInt:
  669. return new UIntConstant (target_type, (uint) Value, Location);
  670. case BuiltinTypeSpec.Type.Long:
  671. return new LongConstant (target_type, (long) Value, Location);
  672. case BuiltinTypeSpec.Type.ULong:
  673. return new ULongConstant (target_type, (ulong) Value, Location);
  674. case BuiltinTypeSpec.Type.Float:
  675. return new FloatConstant (target_type, (float) Value, Location);
  676. case BuiltinTypeSpec.Type.Double:
  677. return new DoubleConstant (target_type, (double) Value, Location);
  678. case BuiltinTypeSpec.Type.Decimal:
  679. return new DecimalConstant (target_type, (decimal) Value, Location);
  680. }
  681. return null;
  682. }
  683. }
  684. public class SByteConstant : IntegralConstant
  685. {
  686. public readonly sbyte Value;
  687. public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
  688. : this (types.SByte, v, loc)
  689. {
  690. }
  691. public SByteConstant (TypeSpec type, sbyte v, Location loc)
  692. : base (type, loc)
  693. {
  694. Value = v;
  695. }
  696. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  697. {
  698. enc.Encode (Value);
  699. }
  700. public override void Emit (EmitContext ec)
  701. {
  702. ec.EmitInt (Value);
  703. }
  704. public override object GetValue ()
  705. {
  706. return Value;
  707. }
  708. public override long GetValueAsLong ()
  709. {
  710. return Value;
  711. }
  712. public override Constant Increment ()
  713. {
  714. return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
  715. }
  716. public override bool IsDefaultValue {
  717. get {
  718. return Value == 0;
  719. }
  720. }
  721. public override bool IsNegative {
  722. get {
  723. return Value < 0;
  724. }
  725. }
  726. public override bool IsOneInteger {
  727. get {
  728. return Value == 1;
  729. }
  730. }
  731. public override bool IsZeroInteger {
  732. get { return Value == 0; }
  733. }
  734. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  735. {
  736. switch (target_type.BuiltinType) {
  737. case BuiltinTypeSpec.Type.Byte:
  738. if (in_checked_context && Value < 0)
  739. throw new OverflowException ();
  740. return new ByteConstant (target_type, (byte) Value, Location);
  741. case BuiltinTypeSpec.Type.Short:
  742. return new ShortConstant (target_type, (short) Value, Location);
  743. case BuiltinTypeSpec.Type.UShort:
  744. if (in_checked_context && Value < 0)
  745. throw new OverflowException ();
  746. return new UShortConstant (target_type, (ushort) Value, Location);
  747. case BuiltinTypeSpec.Type.Int:
  748. return new IntConstant (target_type, (int) Value, Location);
  749. case BuiltinTypeSpec.Type.UInt:
  750. if (in_checked_context && Value < 0)
  751. throw new OverflowException ();
  752. return new UIntConstant (target_type, (uint) Value, Location);
  753. case BuiltinTypeSpec.Type.Long:
  754. return new LongConstant (target_type, (long) Value, Location);
  755. case BuiltinTypeSpec.Type.ULong:
  756. if (in_checked_context && Value < 0)
  757. throw new OverflowException ();
  758. return new ULongConstant (target_type, (ulong) Value, Location);
  759. case BuiltinTypeSpec.Type.Float:
  760. return new FloatConstant (target_type, (float) Value, Location);
  761. case BuiltinTypeSpec.Type.Double:
  762. return new DoubleConstant (target_type, (double) Value, Location);
  763. case BuiltinTypeSpec.Type.Char:
  764. if (in_checked_context && Value < 0)
  765. throw new OverflowException ();
  766. return new CharConstant (target_type, (char) Value, Location);
  767. case BuiltinTypeSpec.Type.Decimal:
  768. return new DecimalConstant (target_type, (decimal) Value, Location);
  769. }
  770. return null;
  771. }
  772. }
  773. public class ShortConstant : IntegralConstant {
  774. public readonly short Value;
  775. public ShortConstant (BuiltinTypes types, short v, Location loc)
  776. : this (types.Short, v, loc)
  777. {
  778. }
  779. public ShortConstant (TypeSpec type, short v, Location loc)
  780. : base (type, loc)
  781. {
  782. Value = v;
  783. }
  784. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  785. {
  786. enc.Encode (Value);
  787. }
  788. public override void Emit (EmitContext ec)
  789. {
  790. ec.EmitInt (Value);
  791. }
  792. public override object GetValue ()
  793. {
  794. return Value;
  795. }
  796. public override long GetValueAsLong ()
  797. {
  798. return Value;
  799. }
  800. public override Constant Increment ()
  801. {
  802. return new ShortConstant (type, checked((short)(Value + 1)), loc);
  803. }
  804. public override bool IsDefaultValue {
  805. get {
  806. return Value == 0;
  807. }
  808. }
  809. public override bool IsZeroInteger {
  810. get { return Value == 0; }
  811. }
  812. public override bool IsNegative {
  813. get {
  814. return Value < 0;
  815. }
  816. }
  817. public override bool IsOneInteger {
  818. get {
  819. return Value == 1;
  820. }
  821. }
  822. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  823. {
  824. switch (target_type.BuiltinType) {
  825. case BuiltinTypeSpec.Type.Byte:
  826. if (in_checked_context) {
  827. if (Value < Byte.MinValue || Value > Byte.MaxValue)
  828. throw new OverflowException ();
  829. }
  830. return new ByteConstant (target_type, (byte) Value, Location);
  831. case BuiltinTypeSpec.Type.SByte:
  832. if (in_checked_context) {
  833. if (Value < SByte.MinValue || Value > SByte.MaxValue)
  834. throw new OverflowException ();
  835. }
  836. return new SByteConstant (target_type, (sbyte) Value, Location);
  837. case BuiltinTypeSpec.Type.UShort:
  838. if (in_checked_context && Value < 0)
  839. throw new OverflowException ();
  840. return new UShortConstant (target_type, (ushort) Value, Location);
  841. case BuiltinTypeSpec.Type.Int:
  842. return new IntConstant (target_type, (int) Value, Location);
  843. case BuiltinTypeSpec.Type.UInt:
  844. if (in_checked_context && Value < 0)
  845. throw new OverflowException ();
  846. return new UIntConstant (target_type, (uint) Value, Location);
  847. case BuiltinTypeSpec.Type.Long:
  848. return new LongConstant (target_type, (long) Value, Location);
  849. case BuiltinTypeSpec.Type.ULong:
  850. if (in_checked_context && Value < 0)
  851. throw new OverflowException ();
  852. return new ULongConstant (target_type, (ulong) Value, Location);
  853. case BuiltinTypeSpec.Type.Float:
  854. return new FloatConstant (target_type, (float) Value, Location);
  855. case BuiltinTypeSpec.Type.Double:
  856. return new DoubleConstant (target_type, (double) Value, Location);
  857. case BuiltinTypeSpec.Type.Char:
  858. if (in_checked_context) {
  859. if (Value < Char.MinValue)
  860. throw new OverflowException ();
  861. }
  862. return new CharConstant (target_type, (char) Value, Location);
  863. case BuiltinTypeSpec.Type.Decimal:
  864. return new DecimalConstant (target_type, (decimal) Value, Location);
  865. }
  866. return null;
  867. }
  868. }
  869. public class UShortConstant : IntegralConstant
  870. {
  871. public readonly ushort Value;
  872. public UShortConstant (BuiltinTypes types, ushort v, Location loc)
  873. : this (types.UShort, v, loc)
  874. {
  875. }
  876. public UShortConstant (TypeSpec type, ushort v, Location loc)
  877. : base (type, loc)
  878. {
  879. Value = v;
  880. }
  881. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  882. {
  883. enc.Encode (Value);
  884. }
  885. public override void Emit (EmitContext ec)
  886. {
  887. ec.EmitInt (Value);
  888. }
  889. public override object GetValue ()
  890. {
  891. return Value;
  892. }
  893. public override long GetValueAsLong ()
  894. {
  895. return Value;
  896. }
  897. public override Constant Increment ()
  898. {
  899. return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
  900. }
  901. public override bool IsDefaultValue {
  902. get {
  903. return Value == 0;
  904. }
  905. }
  906. public override bool IsNegative {
  907. get {
  908. return false;
  909. }
  910. }
  911. public override bool IsOneInteger {
  912. get {
  913. return Value == 1;
  914. }
  915. }
  916. public override bool IsZeroInteger {
  917. get { return Value == 0; }
  918. }
  919. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  920. {
  921. switch (target_type.BuiltinType) {
  922. case BuiltinTypeSpec.Type.Byte:
  923. if (in_checked_context) {
  924. if (Value > Byte.MaxValue)
  925. throw new OverflowException ();
  926. }
  927. return new ByteConstant (target_type, (byte) Value, Location);
  928. case BuiltinTypeSpec.Type.SByte:
  929. if (in_checked_context) {
  930. if (Value > SByte.MaxValue)
  931. throw new OverflowException ();
  932. }
  933. return new SByteConstant (target_type, (sbyte) Value, Location);
  934. case BuiltinTypeSpec.Type.Short:
  935. if (in_checked_context) {
  936. if (Value > Int16.MaxValue)
  937. throw new OverflowException ();
  938. }
  939. return new ShortConstant (target_type, (short) Value, Location);
  940. case BuiltinTypeSpec.Type.Int:
  941. return new IntConstant (target_type, (int) Value, Location);
  942. case BuiltinTypeSpec.Type.UInt:
  943. return new UIntConstant (target_type, (uint) Value, Location);
  944. case BuiltinTypeSpec.Type.Long:
  945. return new LongConstant (target_type, (long) Value, Location);
  946. case BuiltinTypeSpec.Type.ULong:
  947. return new ULongConstant (target_type, (ulong) Value, Location);
  948. case BuiltinTypeSpec.Type.Float:
  949. return new FloatConstant (target_type, (float) Value, Location);
  950. case BuiltinTypeSpec.Type.Double:
  951. return new DoubleConstant (target_type, (double) Value, Location);
  952. case BuiltinTypeSpec.Type.Char:
  953. if (in_checked_context) {
  954. if (Value > Char.MaxValue)
  955. throw new OverflowException ();
  956. }
  957. return new CharConstant (target_type, (char) Value, Location);
  958. case BuiltinTypeSpec.Type.Decimal:
  959. return new DecimalConstant (target_type, (decimal) Value, Location);
  960. }
  961. return null;
  962. }
  963. }
  964. public class IntConstant : IntegralConstant
  965. {
  966. public readonly int Value;
  967. public IntConstant (BuiltinTypes types, int v, Location loc)
  968. : this (types.Int, v, loc)
  969. {
  970. }
  971. public IntConstant (TypeSpec type, int v, Location loc)
  972. : base (type, loc)
  973. {
  974. Value = v;
  975. }
  976. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  977. {
  978. enc.Encode (Value);
  979. }
  980. public override void Emit (EmitContext ec)
  981. {
  982. ec.EmitInt (Value);
  983. }
  984. public override object GetValue ()
  985. {
  986. return Value;
  987. }
  988. public override long GetValueAsLong ()
  989. {
  990. return Value;
  991. }
  992. public override Constant Increment ()
  993. {
  994. return new IntConstant (type, checked(Value + 1), loc);
  995. }
  996. public override bool IsDefaultValue {
  997. get {
  998. return Value == 0;
  999. }
  1000. }
  1001. public override bool IsNegative {
  1002. get {
  1003. return Value < 0;
  1004. }
  1005. }
  1006. public override bool IsOneInteger {
  1007. get {
  1008. return Value == 1;
  1009. }
  1010. }
  1011. public override bool IsZeroInteger {
  1012. get { return Value == 0; }
  1013. }
  1014. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1015. {
  1016. switch (target_type.BuiltinType) {
  1017. case BuiltinTypeSpec.Type.Byte:
  1018. if (in_checked_context) {
  1019. if (Value < Byte.MinValue || Value > Byte.MaxValue)
  1020. throw new OverflowException ();
  1021. }
  1022. return new ByteConstant (target_type, (byte) Value, Location);
  1023. case BuiltinTypeSpec.Type.SByte:
  1024. if (in_checked_context) {
  1025. if (Value < SByte.MinValue || Value > SByte.MaxValue)
  1026. throw new OverflowException ();
  1027. }
  1028. return new SByteConstant (target_type, (sbyte) Value, Location);
  1029. case BuiltinTypeSpec.Type.Short:
  1030. if (in_checked_context) {
  1031. if (Value < Int16.MinValue || Value > Int16.MaxValue)
  1032. throw new OverflowException ();
  1033. }
  1034. return new ShortConstant (target_type, (short) Value, Location);
  1035. case BuiltinTypeSpec.Type.UShort:
  1036. if (in_checked_context) {
  1037. if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
  1038. throw new OverflowException ();
  1039. }
  1040. return new UShortConstant (target_type, (ushort) Value, Location);
  1041. case BuiltinTypeSpec.Type.UInt:
  1042. if (in_checked_context) {
  1043. if (Value < UInt32.MinValue)
  1044. throw new OverflowException ();
  1045. }
  1046. return new UIntConstant (target_type, (uint) Value, Location);
  1047. case BuiltinTypeSpec.Type.Long:
  1048. return new LongConstant (target_type, (long) Value, Location);
  1049. case BuiltinTypeSpec.Type.ULong:
  1050. if (in_checked_context && Value < 0)
  1051. throw new OverflowException ();
  1052. return new ULongConstant (target_type, (ulong) Value, Location);
  1053. case BuiltinTypeSpec.Type.Float:
  1054. return new FloatConstant (target_type, (float) Value, Location);
  1055. case BuiltinTypeSpec.Type.Double:
  1056. return new DoubleConstant (target_type, (double) Value, Location);
  1057. case BuiltinTypeSpec.Type.Char:
  1058. if (in_checked_context) {
  1059. if (Value < Char.MinValue || Value > Char.MaxValue)
  1060. throw new OverflowException ();
  1061. }
  1062. return new CharConstant (target_type, (char) Value, Location);
  1063. case BuiltinTypeSpec.Type.Decimal:
  1064. return new DecimalConstant (target_type, (decimal) Value, Location);
  1065. }
  1066. return null;
  1067. }
  1068. public override Constant ConvertImplicitly (TypeSpec type)
  1069. {
  1070. if (this.type == type)
  1071. return this;
  1072. Constant c = TryImplicitIntConversion (type);
  1073. if (c != null)
  1074. return c; //.Resolve (rc);
  1075. return base.ConvertImplicitly (type);
  1076. }
  1077. /// <summary>
  1078. /// Attempts to perform an implicit constant conversion of the IntConstant
  1079. /// into a different data type using casts (See Implicit Constant
  1080. /// Expression Conversions)
  1081. /// </summary>
  1082. Constant TryImplicitIntConversion (TypeSpec target_type)
  1083. {
  1084. switch (target_type.BuiltinType) {
  1085. case BuiltinTypeSpec.Type.SByte:
  1086. if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
  1087. return new SByteConstant (target_type, (sbyte) Value, loc);
  1088. break;
  1089. case BuiltinTypeSpec.Type.Byte:
  1090. if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
  1091. return new ByteConstant (target_type, (byte) Value, loc);
  1092. break;
  1093. case BuiltinTypeSpec.Type.Short:
  1094. if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
  1095. return new ShortConstant (target_type, (short) Value, loc);
  1096. break;
  1097. case BuiltinTypeSpec.Type.UShort:
  1098. if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
  1099. return new UShortConstant (target_type, (ushort) Value, loc);
  1100. break;
  1101. case BuiltinTypeSpec.Type.UInt:
  1102. if (Value >= 0)
  1103. return new UIntConstant (target_type, (uint) Value, loc);
  1104. break;
  1105. case BuiltinTypeSpec.Type.ULong:
  1106. //
  1107. // we can optimize this case: a positive int32
  1108. // always fits on a uint64. But we need an opcode
  1109. // to do it.
  1110. //
  1111. if (Value >= 0)
  1112. return new ULongConstant (target_type, (ulong) Value, loc);
  1113. break;
  1114. case BuiltinTypeSpec.Type.Double:
  1115. return new DoubleConstant (target_type, (double) Value, loc);
  1116. case BuiltinTypeSpec.Type.Float:
  1117. return new FloatConstant (target_type, (float) Value, loc);
  1118. }
  1119. return null;
  1120. }
  1121. }
  1122. public class UIntConstant : IntegralConstant {
  1123. public readonly uint Value;
  1124. public UIntConstant (BuiltinTypes types, uint v, Location loc)
  1125. : this (types.UInt, v, loc)
  1126. {
  1127. }
  1128. public UIntConstant (TypeSpec type, uint v, Location loc)
  1129. : base (type, loc)
  1130. {
  1131. Value = v;
  1132. }
  1133. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1134. {
  1135. enc.Encode (Value);
  1136. }
  1137. public override void Emit (EmitContext ec)
  1138. {
  1139. ec.EmitInt (unchecked ((int) Value));
  1140. }
  1141. public override object GetValue ()
  1142. {
  1143. return Value;
  1144. }
  1145. public override long GetValueAsLong ()
  1146. {
  1147. return Value;
  1148. }
  1149. public override Constant Increment ()
  1150. {
  1151. return new UIntConstant (type, checked(Value + 1), loc);
  1152. }
  1153. public override bool IsDefaultValue {
  1154. get {
  1155. return Value == 0;
  1156. }
  1157. }
  1158. public override bool IsNegative {
  1159. get {
  1160. return false;
  1161. }
  1162. }
  1163. public override bool IsOneInteger {
  1164. get {
  1165. return Value == 1;
  1166. }
  1167. }
  1168. public override bool IsZeroInteger {
  1169. get { return Value == 0; }
  1170. }
  1171. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1172. {
  1173. switch (target_type.BuiltinType) {
  1174. case BuiltinTypeSpec.Type.Byte:
  1175. if (in_checked_context) {
  1176. if (Value < 0 || Value > byte.MaxValue)
  1177. throw new OverflowException ();
  1178. }
  1179. return new ByteConstant (target_type, (byte) Value, Location);
  1180. case BuiltinTypeSpec.Type.SByte:
  1181. if (in_checked_context) {
  1182. if (Value > SByte.MaxValue)
  1183. throw new OverflowException ();
  1184. }
  1185. return new SByteConstant (target_type, (sbyte) Value, Location);
  1186. case BuiltinTypeSpec.Type.Short:
  1187. if (in_checked_context) {
  1188. if (Value > Int16.MaxValue)
  1189. throw new OverflowException ();
  1190. }
  1191. return new ShortConstant (target_type, (short) Value, Location);
  1192. case BuiltinTypeSpec.Type.UShort:
  1193. if (in_checked_context) {
  1194. if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
  1195. throw new OverflowException ();
  1196. }
  1197. return new UShortConstant (target_type, (ushort) Value, Location);
  1198. case BuiltinTypeSpec.Type.Int:
  1199. if (in_checked_context) {
  1200. if (Value > Int32.MaxValue)
  1201. throw new OverflowException ();
  1202. }
  1203. return new IntConstant (target_type, (int) Value, Location);
  1204. case BuiltinTypeSpec.Type.Long:
  1205. return new LongConstant (target_type, (long) Value, Location);
  1206. case BuiltinTypeSpec.Type.ULong:
  1207. return new ULongConstant (target_type, (ulong) Value, Location);
  1208. case BuiltinTypeSpec.Type.Float:
  1209. return new FloatConstant (target_type, (float) Value, Location);
  1210. case BuiltinTypeSpec.Type.Double:
  1211. return new DoubleConstant (target_type, (double) Value, Location);
  1212. case BuiltinTypeSpec.Type.Char:
  1213. if (in_checked_context) {
  1214. if (Value < Char.MinValue || Value > Char.MaxValue)
  1215. throw new OverflowException ();
  1216. }
  1217. return new CharConstant (target_type, (char) Value, Location);
  1218. case BuiltinTypeSpec.Type.Decimal:
  1219. return new DecimalConstant (target_type, (decimal) Value, Location);
  1220. }
  1221. return null;
  1222. }
  1223. }
  1224. public class LongConstant : IntegralConstant {
  1225. public readonly long Value;
  1226. public LongConstant (BuiltinTypes types, long v, Location loc)
  1227. : this (types.Long, v, loc)
  1228. {
  1229. }
  1230. public LongConstant (TypeSpec type, long v, Location loc)
  1231. : base (type, loc)
  1232. {
  1233. Value = v;
  1234. }
  1235. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1236. {
  1237. enc.Encode (Value);
  1238. }
  1239. public override void Emit (EmitContext ec)
  1240. {
  1241. ec.EmitLong (Value);
  1242. }
  1243. public override object GetValue ()
  1244. {
  1245. return Value;
  1246. }
  1247. public override long GetValueAsLong ()
  1248. {
  1249. return Value;
  1250. }
  1251. public override Constant Increment ()
  1252. {
  1253. return new LongConstant (type, checked(Value + 1), loc);
  1254. }
  1255. public override bool IsDefaultValue {
  1256. get {
  1257. return Value == 0;
  1258. }
  1259. }
  1260. public override bool IsNegative {
  1261. get {
  1262. return Value < 0;
  1263. }
  1264. }
  1265. public override bool IsOneInteger {
  1266. get {
  1267. return Value == 1;
  1268. }
  1269. }
  1270. public override bool IsZeroInteger {
  1271. get { return Value == 0; }
  1272. }
  1273. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1274. {
  1275. switch (target_type.BuiltinType) {
  1276. case BuiltinTypeSpec.Type.Byte:
  1277. if (in_checked_context) {
  1278. if (Value < Byte.MinValue || Value > Byte.MaxValue)
  1279. throw new OverflowException ();
  1280. }
  1281. return new ByteConstant (target_type, (byte) Value, Location);
  1282. case BuiltinTypeSpec.Type.SByte:
  1283. if (in_checked_context) {
  1284. if (Value < SByte.MinValue || Value > SByte.MaxValue)
  1285. throw new OverflowException ();
  1286. }
  1287. return new SByteConstant (target_type, (sbyte) Value, Location);
  1288. case BuiltinTypeSpec.Type.Short:
  1289. if (in_checked_context) {
  1290. if (Value < Int16.MinValue || Value > Int16.MaxValue)
  1291. throw new OverflowException ();
  1292. }
  1293. return new ShortConstant (target_type, (short) Value, Location);
  1294. case BuiltinTypeSpec.Type.UShort:
  1295. if (in_checked_context) {
  1296. if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
  1297. throw new OverflowException ();
  1298. }
  1299. return new UShortConstant (target_type, (ushort) Value, Location);
  1300. case BuiltinTypeSpec.Type.Int:
  1301. if (in_checked_context) {
  1302. if (Value < Int32.MinValue || Value > Int32.MaxValue)
  1303. throw new OverflowException ();
  1304. }
  1305. return new IntConstant (target_type, (int) Value, Location);
  1306. case BuiltinTypeSpec.Type.UInt:
  1307. if (in_checked_context) {
  1308. if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
  1309. throw new OverflowException ();
  1310. }
  1311. return new UIntConstant (target_type, (uint) Value, Location);
  1312. case BuiltinTypeSpec.Type.ULong:
  1313. if (in_checked_context && Value < 0)
  1314. throw new OverflowException ();
  1315. return new ULongConstant (target_type, (ulong) Value, Location);
  1316. case BuiltinTypeSpec.Type.Float:
  1317. return new FloatConstant (target_type, (float) Value, Location);
  1318. case BuiltinTypeSpec.Type.Double:
  1319. return new DoubleConstant (target_type, (double) Value, Location);
  1320. case BuiltinTypeSpec.Type.Char:
  1321. if (in_checked_context) {
  1322. if (Value < Char.MinValue || Value > Char.MaxValue)
  1323. throw new OverflowException ();
  1324. }
  1325. return new CharConstant (target_type, (char) Value, Location);
  1326. case BuiltinTypeSpec.Type.Decimal:
  1327. return new DecimalConstant (target_type, (decimal) Value, Location);
  1328. }
  1329. return null;
  1330. }
  1331. public override Constant ConvertImplicitly (TypeSpec type)
  1332. {
  1333. if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
  1334. return new ULongConstant (type, (ulong) Value, loc);
  1335. }
  1336. return base.ConvertImplicitly (type);
  1337. }
  1338. }
  1339. public class ULongConstant : IntegralConstant {
  1340. public readonly ulong Value;
  1341. public ULongConstant (BuiltinTypes types, ulong v, Location loc)
  1342. : this (types.ULong, v, loc)
  1343. {
  1344. }
  1345. public ULongConstant (TypeSpec type, ulong v, Location loc)
  1346. : base (type, loc)
  1347. {
  1348. Value = v;
  1349. }
  1350. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1351. {
  1352. enc.Encode (Value);
  1353. }
  1354. public override void Emit (EmitContext ec)
  1355. {
  1356. ec.EmitLong (unchecked ((long) Value));
  1357. }
  1358. public override object GetValue ()
  1359. {
  1360. return Value;
  1361. }
  1362. public override long GetValueAsLong ()
  1363. {
  1364. return (long) Value;
  1365. }
  1366. public override Constant Increment ()
  1367. {
  1368. return new ULongConstant (type, checked(Value + 1), loc);
  1369. }
  1370. public override bool IsDefaultValue {
  1371. get {
  1372. return Value == 0;
  1373. }
  1374. }
  1375. public override bool IsNegative {
  1376. get {
  1377. return false;
  1378. }
  1379. }
  1380. public override bool IsOneInteger {
  1381. get {
  1382. return Value == 1;
  1383. }
  1384. }
  1385. public override bool IsZeroInteger {
  1386. get { return Value == 0; }
  1387. }
  1388. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1389. {
  1390. switch (target_type.BuiltinType) {
  1391. case BuiltinTypeSpec.Type.Byte:
  1392. if (in_checked_context && Value > Byte.MaxValue)
  1393. throw new OverflowException ();
  1394. return new ByteConstant (target_type, (byte) Value, Location);
  1395. case BuiltinTypeSpec.Type.SByte:
  1396. if (in_checked_context && Value > ((ulong) SByte.MaxValue))
  1397. throw new OverflowException ();
  1398. return new SByteConstant (target_type, (sbyte) Value, Location);
  1399. case BuiltinTypeSpec.Type.Short:
  1400. if (in_checked_context && Value > ((ulong) Int16.MaxValue))
  1401. throw new OverflowException ();
  1402. return new ShortConstant (target_type, (short) Value, Location);
  1403. case BuiltinTypeSpec.Type.UShort:
  1404. if (in_checked_context && Value > UInt16.MaxValue)
  1405. throw new OverflowException ();
  1406. return new UShortConstant (target_type, (ushort) Value, Location);
  1407. case BuiltinTypeSpec.Type.Int:
  1408. if (in_checked_context && Value > UInt32.MaxValue)
  1409. throw new OverflowException ();
  1410. return new IntConstant (target_type, (int) Value, Location);
  1411. case BuiltinTypeSpec.Type.UInt:
  1412. if (in_checked_context && Value > UInt32.MaxValue)
  1413. throw new OverflowException ();
  1414. return new UIntConstant (target_type, (uint) Value, Location);
  1415. case BuiltinTypeSpec.Type.Long:
  1416. if (in_checked_context && Value > Int64.MaxValue)
  1417. throw new OverflowException ();
  1418. return new LongConstant (target_type, (long) Value, Location);
  1419. case BuiltinTypeSpec.Type.Float:
  1420. return new FloatConstant (target_type, (float) Value, Location);
  1421. case BuiltinTypeSpec.Type.Double:
  1422. return new DoubleConstant (target_type, (double) Value, Location);
  1423. case BuiltinTypeSpec.Type.Char:
  1424. if (in_checked_context && Value > Char.MaxValue)
  1425. throw new OverflowException ();
  1426. return new CharConstant (target_type, (char) Value, Location);
  1427. case BuiltinTypeSpec.Type.Decimal:
  1428. return new DecimalConstant (target_type, (decimal) Value, Location);
  1429. }
  1430. return null;
  1431. }
  1432. }
  1433. public class FloatConstant : Constant {
  1434. //
  1435. // Store constant value as double because float constant operations
  1436. // need to work on double value to match JIT
  1437. //
  1438. public readonly double DoubleValue;
  1439. public FloatConstant (BuiltinTypes types, double v, Location loc)
  1440. : this (types.Float, v, loc)
  1441. {
  1442. }
  1443. public FloatConstant (TypeSpec type, double v, Location loc)
  1444. : base (loc)
  1445. {
  1446. this.type = type;
  1447. eclass = ExprClass.Value;
  1448. DoubleValue = v;
  1449. }
  1450. public override Constant ConvertImplicitly (TypeSpec type)
  1451. {
  1452. if (type.BuiltinType == BuiltinTypeSpec.Type.Double)
  1453. return new DoubleConstant (type, DoubleValue, loc);
  1454. return base.ConvertImplicitly (type);
  1455. }
  1456. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1457. {
  1458. enc.Encode (Value);
  1459. }
  1460. public override void Emit (EmitContext ec)
  1461. {
  1462. ec.Emit (OpCodes.Ldc_R4, Value);
  1463. }
  1464. public float Value {
  1465. get {
  1466. return (float) DoubleValue;
  1467. }
  1468. }
  1469. public override object GetValue ()
  1470. {
  1471. return Value;
  1472. }
  1473. public override string GetValueAsLiteral ()
  1474. {
  1475. return Value.ToString ();
  1476. }
  1477. public override long GetValueAsLong ()
  1478. {
  1479. throw new NotSupportedException ();
  1480. }
  1481. public override bool IsDefaultValue {
  1482. get {
  1483. return Value == 0;
  1484. }
  1485. }
  1486. public override bool IsNegative {
  1487. get {
  1488. return Value < 0;
  1489. }
  1490. }
  1491. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1492. {
  1493. switch (target_type.BuiltinType) {
  1494. case BuiltinTypeSpec.Type.Byte:
  1495. if (in_checked_context) {
  1496. if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
  1497. throw new OverflowException ();
  1498. }
  1499. return new ByteConstant (target_type, (byte) DoubleValue, Location);
  1500. case BuiltinTypeSpec.Type.SByte:
  1501. if (in_checked_context) {
  1502. if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
  1503. throw new OverflowException ();
  1504. }
  1505. return new SByteConstant (target_type, (sbyte) DoubleValue, Location);
  1506. case BuiltinTypeSpec.Type.Short:
  1507. if (in_checked_context) {
  1508. if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
  1509. throw new OverflowException ();
  1510. }
  1511. return new ShortConstant (target_type, (short) DoubleValue, Location);
  1512. case BuiltinTypeSpec.Type.UShort:
  1513. if (in_checked_context) {
  1514. if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
  1515. throw new OverflowException ();
  1516. }
  1517. return new UShortConstant (target_type, (ushort) DoubleValue, Location);
  1518. case BuiltinTypeSpec.Type.Int:
  1519. if (in_checked_context) {
  1520. if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
  1521. throw new OverflowException ();
  1522. }
  1523. return new IntConstant (target_type, (int) DoubleValue, Location);
  1524. case BuiltinTypeSpec.Type.UInt:
  1525. if (in_checked_context) {
  1526. if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
  1527. throw new OverflowException ();
  1528. }
  1529. return new UIntConstant (target_type, (uint) DoubleValue, Location);
  1530. case BuiltinTypeSpec.Type.Long:
  1531. if (in_checked_context) {
  1532. if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
  1533. throw new OverflowException ();
  1534. }
  1535. return new LongConstant (target_type, (long) DoubleValue, Location);
  1536. case BuiltinTypeSpec.Type.ULong:
  1537. if (in_checked_context) {
  1538. if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
  1539. throw new OverflowException ();
  1540. }
  1541. return new ULongConstant (target_type, (ulong) DoubleValue, Location);
  1542. case BuiltinTypeSpec.Type.Double:
  1543. return new DoubleConstant (target_type, DoubleValue, Location);
  1544. case BuiltinTypeSpec.Type.Char:
  1545. if (in_checked_context) {
  1546. if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
  1547. throw new OverflowException ();
  1548. }
  1549. return new CharConstant (target_type, (char) DoubleValue, Location);
  1550. case BuiltinTypeSpec.Type.Decimal:
  1551. return new DecimalConstant (target_type, (decimal) DoubleValue, Location);
  1552. }
  1553. return null;
  1554. }
  1555. }
  1556. public class DoubleConstant : Constant
  1557. {
  1558. public readonly double Value;
  1559. public DoubleConstant (BuiltinTypes types, double v, Location loc)
  1560. : this (types.Double, v, loc)
  1561. {
  1562. }
  1563. public DoubleConstant (TypeSpec type, double v, Location loc)
  1564. : base (loc)
  1565. {
  1566. this.type = type;
  1567. eclass = ExprClass.Value;
  1568. Value = v;
  1569. }
  1570. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1571. {
  1572. enc.Encode (Value);
  1573. }
  1574. public override void Emit (EmitContext ec)
  1575. {
  1576. ec.Emit (OpCodes.Ldc_R8, Value);
  1577. }
  1578. public override object GetValue ()
  1579. {
  1580. return Value;
  1581. }
  1582. public override string GetValueAsLiteral ()
  1583. {
  1584. return Value.ToString ();
  1585. }
  1586. public override long GetValueAsLong ()
  1587. {
  1588. throw new NotSupportedException ();
  1589. }
  1590. public override bool IsDefaultValue {
  1591. get {
  1592. return Value == 0;
  1593. }
  1594. }
  1595. public override bool IsNegative {
  1596. get {
  1597. return Value < 0;
  1598. }
  1599. }
  1600. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1601. {
  1602. switch (target_type.BuiltinType) {
  1603. case BuiltinTypeSpec.Type.Byte:
  1604. if (in_checked_context) {
  1605. if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
  1606. throw new OverflowException ();
  1607. }
  1608. return new ByteConstant (target_type, (byte) Value, Location);
  1609. case BuiltinTypeSpec.Type.SByte:
  1610. if (in_checked_context) {
  1611. if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
  1612. throw new OverflowException ();
  1613. }
  1614. return new SByteConstant (target_type, (sbyte) Value, Location);
  1615. case BuiltinTypeSpec.Type.Short:
  1616. if (in_checked_context) {
  1617. if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
  1618. throw new OverflowException ();
  1619. }
  1620. return new ShortConstant (target_type, (short) Value, Location);
  1621. case BuiltinTypeSpec.Type.UShort:
  1622. if (in_checked_context) {
  1623. if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
  1624. throw new OverflowException ();
  1625. }
  1626. return new UShortConstant (target_type, (ushort) Value, Location);
  1627. case BuiltinTypeSpec.Type.Int:
  1628. if (in_checked_context) {
  1629. if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
  1630. throw new OverflowException ();
  1631. }
  1632. return new IntConstant (target_type, (int) Value, Location);
  1633. case BuiltinTypeSpec.Type.UInt:
  1634. if (in_checked_context) {
  1635. if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
  1636. throw new OverflowException ();
  1637. }
  1638. return new UIntConstant (target_type, (uint) Value, Location);
  1639. case BuiltinTypeSpec.Type.Long:
  1640. if (in_checked_context) {
  1641. if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
  1642. throw new OverflowException ();
  1643. }
  1644. return new LongConstant (target_type, (long) Value, Location);
  1645. case BuiltinTypeSpec.Type.ULong:
  1646. if (in_checked_context) {
  1647. if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
  1648. throw new OverflowException ();
  1649. }
  1650. return new ULongConstant (target_type, (ulong) Value, Location);
  1651. case BuiltinTypeSpec.Type.Float:
  1652. return new FloatConstant (target_type, (float) Value, Location);
  1653. case BuiltinTypeSpec.Type.Char:
  1654. if (in_checked_context) {
  1655. if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
  1656. throw new OverflowException ();
  1657. }
  1658. return new CharConstant (target_type, (char) Value, Location);
  1659. case BuiltinTypeSpec.Type.Decimal:
  1660. return new DecimalConstant (target_type, (decimal) Value, Location);
  1661. }
  1662. return null;
  1663. }
  1664. }
  1665. public class DecimalConstant : Constant {
  1666. public readonly decimal Value;
  1667. public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
  1668. : this (types.Decimal, d, loc)
  1669. {
  1670. }
  1671. public DecimalConstant (TypeSpec type, decimal d, Location loc)
  1672. : base (loc)
  1673. {
  1674. this.type = type;
  1675. eclass = ExprClass.Value;
  1676. Value = d;
  1677. }
  1678. public override void Emit (EmitContext ec)
  1679. {
  1680. MethodSpec m;
  1681. int [] words = decimal.GetBits (Value);
  1682. int power = (words [3] >> 16) & 0xff;
  1683. if (power == 0) {
  1684. if (Value <= int.MaxValue && Value >= int.MinValue) {
  1685. m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
  1686. if (m == null) {
  1687. return;
  1688. }
  1689. ec.EmitInt ((int) Value);
  1690. ec.Emit (OpCodes.Newobj, m);
  1691. return;
  1692. }
  1693. if (Value <= long.MaxValue && Value >= long.MinValue) {
  1694. m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
  1695. if (m == null) {
  1696. return;
  1697. }
  1698. ec.EmitLong ((long) Value);
  1699. ec.Emit (OpCodes.Newobj, m);
  1700. return;
  1701. }
  1702. }
  1703. ec.EmitInt (words [0]);
  1704. ec.EmitInt (words [1]);
  1705. ec.EmitInt (words [2]);
  1706. // sign
  1707. ec.EmitInt (words [3] >> 31);
  1708. // power
  1709. ec.EmitInt (power);
  1710. m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
  1711. if (m != null) {
  1712. ec.Emit (OpCodes.Newobj, m);
  1713. }
  1714. }
  1715. public override bool IsDefaultValue {
  1716. get {
  1717. return Value == 0;
  1718. }
  1719. }
  1720. public override bool IsNegative {
  1721. get {
  1722. return Value < 0;
  1723. }
  1724. }
  1725. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1726. {
  1727. switch (target_type.BuiltinType) {
  1728. case BuiltinTypeSpec.Type.SByte:
  1729. return new SByteConstant (target_type, (sbyte) Value, loc);
  1730. case BuiltinTypeSpec.Type.Byte:
  1731. return new ByteConstant (target_type, (byte) Value, loc);
  1732. case BuiltinTypeSpec.Type.Short:
  1733. return new ShortConstant (target_type, (short) Value, loc);
  1734. case BuiltinTypeSpec.Type.UShort:
  1735. return new UShortConstant (target_type, (ushort) Value, loc);
  1736. case BuiltinTypeSpec.Type.Int:
  1737. return new IntConstant (target_type, (int) Value, loc);
  1738. case BuiltinTypeSpec.Type.UInt:
  1739. return new UIntConstant (target_type, (uint) Value, loc);
  1740. case BuiltinTypeSpec.Type.Long:
  1741. return new LongConstant (target_type, (long) Value, loc);
  1742. case BuiltinTypeSpec.Type.ULong:
  1743. return new ULongConstant (target_type, (ulong) Value, loc);
  1744. case BuiltinTypeSpec.Type.Char:
  1745. return new CharConstant (target_type, (char) Value, loc);
  1746. case BuiltinTypeSpec.Type.Float:
  1747. return new FloatConstant (target_type, (float) Value, loc);
  1748. case BuiltinTypeSpec.Type.Double:
  1749. return new DoubleConstant (target_type, (double) Value, loc);
  1750. }
  1751. return null;
  1752. }
  1753. public override object GetValue ()
  1754. {
  1755. return Value;
  1756. }
  1757. public override string GetValueAsLiteral ()
  1758. {
  1759. return Value.ToString () + "M";
  1760. }
  1761. public override long GetValueAsLong ()
  1762. {
  1763. throw new NotSupportedException ();
  1764. }
  1765. }
  1766. public class StringConstant : Constant {
  1767. public StringConstant (BuiltinTypes types, string s, Location loc)
  1768. : this (types.String, s, loc)
  1769. {
  1770. }
  1771. public StringConstant (TypeSpec type, string s, Location loc)
  1772. : base (loc)
  1773. {
  1774. this.type = type;
  1775. eclass = ExprClass.Value;
  1776. Value = s;
  1777. }
  1778. protected StringConstant (Location loc)
  1779. : base (loc)
  1780. {
  1781. }
  1782. public string Value { get; protected set; }
  1783. public override object GetValue ()
  1784. {
  1785. return Value;
  1786. }
  1787. public override string GetValueAsLiteral ()
  1788. {
  1789. // FIXME: Escape the string.
  1790. return "\"" + Value + "\"";
  1791. }
  1792. public override long GetValueAsLong ()
  1793. {
  1794. throw new NotSupportedException ();
  1795. }
  1796. public override void Emit (EmitContext ec)
  1797. {
  1798. if (Value == null) {
  1799. ec.EmitNull ();
  1800. return;
  1801. }
  1802. //
  1803. // Use string.Empty for both literals and constants even if
  1804. // it's not allowed at language level
  1805. //
  1806. if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
  1807. var string_type = ec.BuiltinTypes.String;
  1808. if (ec.CurrentType != string_type) {
  1809. var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
  1810. if (m != null) {
  1811. ec.Emit (OpCodes.Ldsfld, m);
  1812. return;
  1813. }
  1814. }
  1815. }
  1816. ec.Emit (OpCodes.Ldstr, Value);
  1817. }
  1818. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1819. {
  1820. // cast to object
  1821. if (type != targetType)
  1822. enc.Encode (type);
  1823. enc.Encode (Value);
  1824. }
  1825. public override bool IsDefaultValue {
  1826. get {
  1827. return Value == null;
  1828. }
  1829. }
  1830. public override bool IsNegative {
  1831. get {
  1832. return false;
  1833. }
  1834. }
  1835. public override bool IsNull {
  1836. get {
  1837. return IsDefaultValue;
  1838. }
  1839. }
  1840. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  1841. {
  1842. return null;
  1843. }
  1844. public override Constant ConvertImplicitly (TypeSpec type)
  1845. {
  1846. if (IsDefaultValue && type.BuiltinType == BuiltinTypeSpec.Type.Object)
  1847. return new NullConstant (type, loc);
  1848. return base.ConvertImplicitly (type);
  1849. }
  1850. }
  1851. class NameOf : StringConstant
  1852. {
  1853. readonly SimpleName name;
  1854. public NameOf (SimpleName name)
  1855. : base (name.Location)
  1856. {
  1857. this.name = name;
  1858. }
  1859. protected override Expression DoResolve (ResolveContext rc)
  1860. {
  1861. throw new NotSupportedException ();
  1862. }
  1863. bool ResolveArgumentExpression (ResolveContext rc, Expression expr)
  1864. {
  1865. var sn = expr as SimpleName;
  1866. if (sn != null) {
  1867. Value = sn.Name;
  1868. if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_6)
  1869. rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, Location, "nameof operator");
  1870. if (sn.HasTypeArguments) {
  1871. // TODO: csc compatible but unhelpful error message
  1872. rc.Report.Error (1001, loc, "Identifier expected");
  1873. return true;
  1874. }
  1875. sn.LookupNameExpression (rc, MemberLookupRestrictions.IgnoreArity | MemberLookupRestrictions.IgnoreAmbiguity);
  1876. return true;
  1877. }
  1878. var ma = expr as MemberAccess;
  1879. if (ma != null) {
  1880. FullNamedExpression fne = ma.LeftExpression as ATypeNameExpression;
  1881. if (fne == null) {
  1882. var qam = ma as QualifiedAliasMember;
  1883. if (qam == null)
  1884. return false;
  1885. fne = qam.CreateExpressionFromAlias (rc);
  1886. if (fne == null)
  1887. return true;
  1888. }
  1889. Value = ma.Name;
  1890. if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_6)
  1891. rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, Location, "nameof operator");
  1892. if (ma.HasTypeArguments) {
  1893. // TODO: csc compatible but unhelpful error message
  1894. rc.Report.Error (1001, loc, "Identifier expected");
  1895. return true;
  1896. }
  1897. var left = fne.ResolveAsTypeOrNamespace (rc, true);
  1898. if (left == null)
  1899. return true;
  1900. var ns = left as NamespaceExpression;
  1901. if (ns != null) {
  1902. FullNamedExpression retval = ns.LookupTypeOrNamespace (rc, ma.Name, 0, LookupMode.NameOf, loc);
  1903. if (retval == null)
  1904. ns.Error_NamespaceDoesNotExist (rc, ma.Name, 0);
  1905. return true;
  1906. }
  1907. if (left.Type.IsGenericOrParentIsGeneric && left.Type.GetDefinition () != left.Type) {
  1908. rc.Report.Error (8071, loc, "Type arguments are not allowed in the nameof operator");
  1909. }
  1910. var mexpr = MemberLookup (rc, false, left.Type, ma.Name, 0, MemberLookupRestrictions.IgnoreArity | MemberLookupRestrictions.IgnoreAmbiguity, loc);
  1911. if (mexpr == null) {
  1912. ma.Error_IdentifierNotFound (rc, left.Type);
  1913. return true;
  1914. }
  1915. return true;
  1916. }
  1917. return false;
  1918. }
  1919. public Expression ResolveOverload (ResolveContext rc, Arguments args)
  1920. {
  1921. if (args == null || args.Count != 1) {
  1922. name.Error_NameDoesNotExist (rc);
  1923. return null;
  1924. }
  1925. var arg = args [0];
  1926. var res = ResolveArgumentExpression (rc, arg.Expr);
  1927. if (!res) {
  1928. name.Error_NameDoesNotExist (rc);
  1929. return null;
  1930. }
  1931. type = rc.BuiltinTypes.String;
  1932. eclass = ExprClass.Value;
  1933. return this;
  1934. }
  1935. }
  1936. //
  1937. // Null constant can have its own type, think of `default (Foo)'
  1938. //
  1939. public class NullConstant : Constant
  1940. {
  1941. public NullConstant (TypeSpec type, Location loc)
  1942. : base (loc)
  1943. {
  1944. eclass = ExprClass.Value;
  1945. this.type = type;
  1946. }
  1947. public override Expression CreateExpressionTree (ResolveContext ec)
  1948. {
  1949. if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
  1950. // Optimized version, also avoids referencing literal internal type
  1951. Arguments args = new Arguments (1);
  1952. args.Add (new Argument (this));
  1953. return CreateExpressionFactoryCall (ec, "Constant", args);
  1954. }
  1955. return base.CreateExpressionTree (ec);
  1956. }
  1957. public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType)
  1958. {
  1959. switch (targetType.BuiltinType) {
  1960. case BuiltinTypeSpec.Type.Object:
  1961. // Type it as string cast
  1962. enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
  1963. goto case BuiltinTypeSpec.Type.String;
  1964. case BuiltinTypeSpec.Type.String:
  1965. case BuiltinTypeSpec.Type.Type:
  1966. enc.Encode (byte.MaxValue);
  1967. return;
  1968. default:
  1969. var ac = targetType as ArrayContainer;
  1970. if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
  1971. enc.Encode (uint.MaxValue);
  1972. return;
  1973. }
  1974. break;
  1975. }
  1976. base.EncodeAttributeValue (rc, enc, targetType, parameterType);
  1977. }
  1978. public override void Emit (EmitContext ec)
  1979. {
  1980. ec.EmitNull ();
  1981. // Only to make verifier happy
  1982. if (type.IsGenericParameter)
  1983. ec.Emit (OpCodes.Unbox_Any, type);
  1984. }
  1985. public override string ExprClassName {
  1986. get {
  1987. return GetSignatureForError ();
  1988. }
  1989. }
  1990. public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
  1991. {
  1992. if (targetType.IsPointer) {
  1993. if (IsLiteral || this is NullPointer)
  1994. return new NullPointer (targetType, loc);
  1995. return null;
  1996. }
  1997. // Exlude internal compiler types
  1998. if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
  1999. return null;
  2000. if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
  2001. return null;
  2002. if (TypeSpec.IsReferenceType (targetType))
  2003. return new NullConstant (targetType, loc);
  2004. if (targetType.IsNullableType)
  2005. return Nullable.LiftedNull.Create (targetType, loc);
  2006. return null;
  2007. }
  2008. public override Constant ConvertImplicitly (TypeSpec targetType)
  2009. {
  2010. return ConvertExplicitly (false, targetType);
  2011. }
  2012. public override string GetSignatureForError ()
  2013. {
  2014. return "null";
  2015. }
  2016. public override object GetValue ()
  2017. {
  2018. return null;
  2019. }
  2020. public override string GetValueAsLiteral ()
  2021. {
  2022. return GetSignatureForError ();
  2023. }
  2024. public override long GetValueAsLong ()
  2025. {
  2026. throw new NotSupportedException ();
  2027. }
  2028. public override bool IsDefaultValue {
  2029. get { return true; }
  2030. }
  2031. public override bool IsNegative {
  2032. get { return false; }
  2033. }
  2034. public override bool IsNull {
  2035. get { return true; }
  2036. }
  2037. public override bool IsZeroInteger {
  2038. get { return true; }
  2039. }
  2040. }
  2041. //
  2042. // A null constant in a pointer context
  2043. //
  2044. class NullPointer : NullConstant
  2045. {
  2046. public NullPointer (TypeSpec type, Location loc)
  2047. : base (type, loc)
  2048. {
  2049. }
  2050. public override Expression CreateExpressionTree (ResolveContext ec)
  2051. {
  2052. Error_PointerInsideExpressionTree (ec);
  2053. return base.CreateExpressionTree (ec);
  2054. }
  2055. public override void Emit (EmitContext ec)
  2056. {
  2057. //
  2058. // Emits null pointer
  2059. //
  2060. ec.EmitInt (0);
  2061. ec.Emit (OpCodes.Conv_U);
  2062. }
  2063. }
  2064. /// <summary>
  2065. /// The value is constant, but when emitted has a side effect. This is
  2066. /// used by BitwiseAnd to ensure that the second expression is invoked
  2067. /// regardless of the value of the left side.
  2068. /// </summary>
  2069. public class SideEffectConstant : Constant
  2070. {
  2071. public readonly Constant value;
  2072. Expression side_effect;
  2073. public SideEffectConstant (Constant value, Expression side_effect, Location loc)
  2074. : base (loc)
  2075. {
  2076. this.value = value;
  2077. type = value.Type;
  2078. eclass = ExprClass.Value;
  2079. while (side_effect is SideEffectConstant)
  2080. side_effect = ((SideEffectConstant) side_effect).side_effect;
  2081. this.side_effect = side_effect;
  2082. }
  2083. public override bool IsSideEffectFree {
  2084. get {
  2085. return false;
  2086. }
  2087. }
  2088. public override bool ContainsEmitWithAwait ()
  2089. {
  2090. return side_effect.ContainsEmitWithAwait ();
  2091. }
  2092. public override object GetValue ()
  2093. {
  2094. return value.GetValue ();
  2095. }
  2096. public override string GetValueAsLiteral ()
  2097. {
  2098. return value.GetValueAsLiteral ();
  2099. }
  2100. public override long GetValueAsLong ()
  2101. {
  2102. return value.GetValueAsLong ();
  2103. }
  2104. public override void Emit (EmitContext ec)
  2105. {
  2106. side_effect.EmitSideEffect (ec);
  2107. value.Emit (ec);
  2108. }
  2109. public override void EmitSideEffect (EmitContext ec)
  2110. {
  2111. side_effect.EmitSideEffect (ec);
  2112. value.EmitSideEffect (ec);
  2113. }
  2114. public override void FlowAnalysis (FlowAnalysisContext fc)
  2115. {
  2116. side_effect.FlowAnalysis (fc);
  2117. }
  2118. public override bool IsDefaultValue {
  2119. get { return value.IsDefaultValue; }
  2120. }
  2121. public override bool IsNegative {
  2122. get { return value.IsNegative; }
  2123. }
  2124. public override bool IsZeroInteger {
  2125. get { return value.IsZeroInteger; }
  2126. }
  2127. public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
  2128. {
  2129. Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
  2130. if (new_value == null)
  2131. return null;
  2132. var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
  2133. c.type = target_type;
  2134. c.eclass = eclass;
  2135. return c;
  2136. }
  2137. }
  2138. }