internal override void WriteTo(CCodeWriterBase c) { var asIntValue = false; var isEnum = Type != null && Type.TypeKind == TypeKind.Enum; if (isEnum) { object value = null; switch (this.Value.Discriminator) { case ConstantValueTypeDiscriminator.Null: break; case ConstantValueTypeDiscriminator.SByte: value = this.Value.SByteValue; break; case ConstantValueTypeDiscriminator.Byte: value = this.Value.ByteValue; break; case ConstantValueTypeDiscriminator.Int16: value = this.Value.Int16Value; break; case ConstantValueTypeDiscriminator.UInt16: value = this.Value.UInt16Value; break; case ConstantValueTypeDiscriminator.Char: value = this.Value.CharValue; break; case ConstantValueTypeDiscriminator.Int32: value = this.Value.Int32Value; break; case ConstantValueTypeDiscriminator.UInt32: value = this.Value.UInt32Value; break; case ConstantValueTypeDiscriminator.Int64: value = this.Value.Int64Value; break; case ConstantValueTypeDiscriminator.UInt64: value = this.Value.UInt64Value; break; case ConstantValueTypeDiscriminator.Single: value = this.Value.SingleValue; break; case ConstantValueTypeDiscriminator.Double: value = this.Value.DoubleValue; break; case ConstantValueTypeDiscriminator.String: value = this.Value.StringValue; break; case ConstantValueTypeDiscriminator.Boolean: value = this.Value.BooleanValue; break; default: throw new NotSupportedException(); } var field = Type.GetMembers().OfType <IFieldSymbol>().FirstOrDefault(f => f.HasConstantValue && f.ConstantValue.Equals(value)); if (field != null) { c.WriteNamespace(Type.ContainingNamespace, containingNamespace: MethodOwner?.ContainingNamespace); c.WriteFieldAccessAsStaticField(field, enumAsConst: true); return; } else { // treat it as flags (fallback scenario) asIntValue = true; } } if (asIntValue) { c.TextSpan("("); c.WriteType(Type, containingNamespace: MethodOwner?.ContainingNamespace); c.TextSpan(")"); } var discriminator = this.Value.Discriminator; switch (discriminator) { case ConstantValueTypeDiscriminator.Null: c.TextSpan("nullptr"); break; case ConstantValueTypeDiscriminator.SByte: if (sbyte.MaxValue == this.Value.SByteValue) { c.TextSpan("std::numeric_limits<int8_t>::max()"); } else if (sbyte.MinValue == this.Value.SByteValue) { c.TextSpan("std::numeric_limits<int8_t>::min()"); } else { c.TextSpan("(int8_t)"); c.TextSpan(this.Value.SByteValue.ToString()); } break; case ConstantValueTypeDiscriminator.Byte: if (byte.MaxValue == this.Value.ByteValue) { c.TextSpan("std::numeric_limits<uint8_t>::max()"); } else if (byte.MinValue == this.Value.ByteValue) { c.TextSpan("std::numeric_limits<uint8_t>::min()"); } else { c.TextSpan("(uint8_t)"); c.TextSpan(this.Value.ByteValue.ToString()); } break; case ConstantValueTypeDiscriminator.Int16: if (short.MaxValue == this.Value.Int16Value) { c.TextSpan("std::numeric_limits<int16_t>::max()"); } else if (short.MinValue == this.Value.Int16Value) { c.TextSpan("std::numeric_limits<int16_t>::min()"); } else { c.TextSpan("(int16_t)"); c.TextSpan(this.Value.Int16Value.ToString()); } break; case ConstantValueTypeDiscriminator.UInt16: if (ushort.MaxValue == this.Value.UInt16Value) { c.TextSpan("std::numeric_limits<uint16_t>::max()"); } else if (ushort.MinValue == this.Value.UInt16Value) { c.TextSpan("std::numeric_limits<uint16_t>::min()"); } else { c.TextSpan("(uint16_t)"); c.TextSpan(this.Value.UInt16Value.ToString()); } break; case ConstantValueTypeDiscriminator.Char: c.TextSpan(string.Format("u'{0}'", UnicodeChar(this.Value.CharValue))); break; case ConstantValueTypeDiscriminator.Int32: if (int.MaxValue == this.Value.Int32Value) { c.TextSpan("std::numeric_limits<int32_t>::max()"); } else if (int.MinValue == this.Value.Int32Value) { c.TextSpan("std::numeric_limits<int32_t>::min()"); } else { c.TextSpan(this.Value.Int32Value.ToString()); } break; case ConstantValueTypeDiscriminator.UInt32: if (uint.MaxValue == this.Value.UInt32Value) { c.TextSpan("std::numeric_limits<uint32_t>::max()"); } else if (uint.MinValue == this.Value.UInt32Value) { c.TextSpan("std::numeric_limits<uint32_t>::min()"); } else { c.TextSpan(this.Value.UInt32Value.ToString()); c.TextSpan("U"); } break; case ConstantValueTypeDiscriminator.Int64: if (long.MaxValue == this.Value.Int64Value) { c.TextSpan("std::numeric_limits<int64_t>::max()"); } else if (long.MinValue == this.Value.Int64Value) { c.TextSpan("std::numeric_limits<int64_t>::min()"); } else { c.TextSpan("(int64_t)"); c.TextSpan(this.Value.Int64Value.ToString()); c.TextSpan("LL"); } break; case ConstantValueTypeDiscriminator.UInt64: if (ulong.MaxValue == this.Value.UInt64Value) { c.TextSpan("std::numeric_limits<uint64_t>::max()"); } else if (ulong.MinValue == this.Value.UInt64Value) { c.TextSpan("std::numeric_limits<uint64_t>::min()"); } else { c.TextSpan("(uint64_t)"); c.TextSpan(this.Value.UInt64Value.ToString()); c.TextSpan("ULL"); } break; case ConstantValueTypeDiscriminator.Single: if (float.IsPositiveInfinity(this.Value.SingleValue)) { c.TextSpan("std::numeric_limits<float>::infinity()"); } else if (float.IsNegativeInfinity(this.Value.SingleValue)) { c.TextSpan("-std::numeric_limits<float>::infinity()"); } else if (float.IsNaN(this.Value.SingleValue)) { c.TextSpan("std::numeric_limits<float>::quiet_NaN()"); } else if (float.MaxValue == this.Value.SingleValue) { c.TextSpan("std::numeric_limits<float>::max()"); } else if (float.MinValue == this.Value.SingleValue) { c.TextSpan("std::numeric_limits<float>::min()"); } else { var line = this.Value.SingleValue.ToString(); c.TextSpan(line.IndexOf('.') != -1 || line.IndexOf('E') != -1 ? line : string.Concat(line, ".0")); c.TextSpan("f"); } break; case ConstantValueTypeDiscriminator.Double: if (double.IsPositiveInfinity(this.Value.DoubleValue)) { c.TextSpan("std::numeric_limits<double>::infinity()"); } else if (double.IsNegativeInfinity(this.Value.DoubleValue)) { c.TextSpan("-std::numeric_limits<double>::infinity()"); } else if (double.IsNaN(this.Value.DoubleValue)) { c.TextSpan("std::numeric_limits<double>::quiet_NaN()"); } else if (double.MaxValue == this.Value.DoubleValue) { c.TextSpan("std::numeric_limits<double>::max()"); } else if (double.MinValue == this.Value.DoubleValue) { c.TextSpan("std::numeric_limits<double>::min()"); } else { var line = this.Value.DoubleValue.ToString(); c.TextSpan(line.IndexOf('.') != -1 || line.IndexOf('E') != -1 ? line : string.Concat(line, ".0")); } break; case ConstantValueTypeDiscriminator.String: c.TextSpan(string.Format("u\"{0}\"", UnicodeString(this.Value.StringValue))); if (!CppConstString) { c.TextSpan("_s"); } break; case ConstantValueTypeDiscriminator.Boolean: c.TextSpan(this.Value.BooleanValue.ToString().ToLowerInvariant()); break; default: throw new NotSupportedException(); } }