private static void WriteTemplateTraits(CCodeWriterText c, INamedTypeSymbol namedTypeSymbol) { if (namedTypeSymbol.IsPrimitiveValueType() || namedTypeSymbol.TypeKind == TypeKind.Enum || namedTypeSymbol.SpecialType == SpecialType.System_Void) { // value to class c.TextSpanNewLine("template<>"); c.TextSpan("struct"); c.WhiteSpace(); c.TextSpan("valuetype_to_class<"); c.WriteType(namedTypeSymbol); c.TextSpan(">"); c.WhiteSpace(); c.TextSpan("{ typedef"); c.WhiteSpace(); c.WriteType(namedTypeSymbol, true, false, true); c.WhiteSpace(); c.TextSpanNewLine("type; };"); // class to value c.TextSpanNewLine("template<>"); c.TextSpan("struct"); c.WhiteSpace(); c.TextSpan("class_to_valuetype<"); c.WriteType(namedTypeSymbol, true, false, true); c.TextSpan(">"); c.WhiteSpace(); c.TextSpan("{ typedef"); c.WhiteSpace(); c.WriteType(namedTypeSymbol); c.WhiteSpace(); c.TextSpanNewLine("type; };"); // map class to valuetype if (namedTypeSymbol.IsAtomicType()) { c.TextSpanNewLine("template<>"); c.TextSpan("struct gc_traits<"); c.WriteType(namedTypeSymbol, true, false, true); c.TextSpanNewLine("> { constexpr static const GCAtomic value = GCAtomic::Default; };"); } } // type holder var isTypeHolder = namedTypeSymbol.SpecialType == SpecialType.None && namedTypeSymbol.TypeKind == TypeKind.Struct && namedTypeSymbol.Name.EndsWith("__type"); var isNotModule = namedTypeSymbol.Name != "<Module>"; if (!isTypeHolder && isNotModule) { c.TextSpan("template<"); if (namedTypeSymbol.IsGenericType || namedTypeSymbol.IsAnonymousType) { c.WriteTemplateDefinitionParameters(namedTypeSymbol); } c.TextSpanNewLine(">"); c.TextSpan("struct"); c.WhiteSpace(); c.TextSpan("type_holder<"); c.WriteType(namedTypeSymbol, true, false, true); c.TextSpan(">"); c.WhiteSpace(); c.TextSpan("{ typedef"); c.WhiteSpace(); c.WriteType(namedTypeSymbol, true, false, true, typeOfName: true); c.WhiteSpace(); c.TextSpanNewLine("type; };"); } }