string GetTypeCode(CppType mangleType, Dictionary <string, int> compressMap) { CppTypes element = mangleType.ElementType; IEnumerable <CppModifiers> modifiers = mangleType.Modifiers; StringBuilder code = new StringBuilder(); var ptrOrRef = For.AnyInputIn(CppModifiers.Pointer, CppModifiers.Reference); var modifierCode = modifiers.Reverse().Transform( For.AnyInputIn(CppModifiers.Pointer, CppModifiers.Array).Emit("P"), For.AnyInputIn(CppModifiers.Reference).Emit("R"), // Itanium mangled names do not include const or volatile unless // they modify the type pointed to by pointer or reference. Choose.TopOne( For.AllInputsIn(CppModifiers.Volatile, CppModifiers.Const).InAnyOrder().After(ptrOrRef).Emit("VK"), For.AnyInputIn(CppModifiers.Volatile).After(ptrOrRef).Emit("V"), For.AnyInputIn(CppModifiers.Const).After(ptrOrRef).Emit("K") ) ); code.Append(string.Join(string.Empty, modifierCode.ToArray())); int modifierLength = code.Length; switch (element) { case CppTypes.Int: code.Append(modifiers.Transform( For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder().Emit('t'), For.AnyInputIn(CppModifiers.Short).Emit('s'), For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Long, CppModifiers.Long).InAnyOrder().Emit('y'), For.AllInputsIn(CppModifiers.Long, CppModifiers.Long).InAnyOrder().Emit('x'), For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Long).InAnyOrder().Emit('m'), For.AnyInputIn(CppModifiers.Long).Emit('l'), For.AnyInputIn(CppModifiers.Unsigned).Emit('j') ).DefaultIfEmpty('i').ToArray()); break; case CppTypes.Bool: code.Append('b'); break; case CppTypes.Char: if (modifiers.Contains(CppModifiers.Signed)) { code.Append('a'); } else if (modifiers.Contains(CppModifiers.Unsigned)) { code.Append('h'); } else { code.Append('c'); } break; case CppTypes.Float: code.Append('f'); break; case CppTypes.Double: if (modifiers.Contains(CppModifiers.Long)) { code.Append('e'); } else { code.Append('d'); } break; case CppTypes.Class: case CppTypes.Struct: case CppTypes.Union: case CppTypes.Enum: // TODO: This is getting a little ridiculous and should probably be refactored... // Determine if we have any namespaces to print out bool hasNamespace = (mangleType.Namespaces != null); if (hasNamespace) { code.Append('N'); foreach (var ns in mangleType.Namespaces) { code.Append(GetIdentifier(compressMap, ns)); } } // Look up the type by itself first // NOTE: Order here is important so that they get sequenced properly bool foundType; string value = GetIdentifier(compressMap, mangleType.ElementTypeName, 0, out foundType); if (modifierLength > 0) { // Next lookup the type with modifiers for a match bool foundExact; string exact = GetIdentifier(compressMap, mangleType.ToString(), modifierLength, out foundExact); if (foundExact) { // Use the exact values sequence ID and remove all modifiers and namespaces code.Length = 0; hasNamespace = false; value = exact; } else if (foundType) { // We didn't get an exact match but we know the type // so remove the namespaces, but not the modifiers code.Length = modifierLength; hasNamespace = false; } } // Print out our class identifier code.Append(value); // If we're printing out namespaces then signal the end of the namespace if (hasNamespace) { code.Append('E'); } // Since we handle the modifier compression in here make sure we skip the logic below modifierLength = 0; break; } // If there were modifiers then always add it to the compression map // NOTE: If there were multiple modifiers this causes us to skip sequence numbers if (modifierLength > 0) { bool found; string value = GetIdentifier(compressMap, mangleType.ToString(), modifierLength, out found); if (found) { return(value); } } return(code.ToString()); }
public virtual string GetTypeCode(CppType mangleType) { CppTypes element = mangleType.ElementType; IEnumerable <CppModifiers> modifiers = mangleType.Modifiers; StringBuilder code = new StringBuilder(); var ptr = For.AnyInputIn(CppModifiers.Pointer); var ptrRefOrArray = For.AnyInputIn(CppModifiers.Pointer, CppModifiers.Reference, CppModifiers.Array); var modifierCode = modifiers.Reverse().Transform( Choose.TopOne( For.AllInputsIn(CppModifiers.Const, CppModifiers.Volatile).InAnyOrder().After(ptrRefOrArray).Emit('D'), For.AnyInputIn(CppModifiers.Const).After(ptrRefOrArray).Emit('B'), For.AnyInputIn(CppModifiers.Volatile).After(ptrRefOrArray).Emit('C'), For.AnyInput <CppModifiers> ().After(ptrRefOrArray).Emit('A') ), For.AnyInputIn(CppModifiers.Array).Emit('Q'), For.AnyInputIn(CppModifiers.Reference).Emit('A'), Choose.TopOne( ptr.After().AllInputsIn(CppModifiers.Const, CppModifiers.Volatile).InAnyOrder().Emit('S'), ptr.After().AnyInputIn(CppModifiers.Const).Emit('Q'), ptr.After().AnyInputIn(CppModifiers.Volatile).Emit('R'), ptr.Emit('P') ), ptrRefOrArray.AtEnd().Emit('A') ); code.Append(modifierCode.ToArray()); switch (element) { case CppTypes.Void: code.Append('X'); break; case CppTypes.Int: code.Append(modifiers.Transform( For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder().Emit('G') ).DefaultIfEmpty('H').ToArray()); break; case CppTypes.Char: code.Append('D'); break; case CppTypes.Class: code.Append('V'); code.Append(mangleType.ElementTypeName); code.Append("@@"); break; case CppTypes.Struct: code.Append('U'); code.Append(mangleType.ElementTypeName); code.Append("@@"); break; case CppTypes.Union: code.Append('T'); code.Append(mangleType.ElementTypeName); code.Append("@@"); break; case CppTypes.Enum: code.Append("W4"); code.Append(mangleType.ElementTypeName); code.Append("@@"); break; } return(code.ToString()); }
string GetTypeCode(CppType mangleType, Dictionary <string, int> compressMap) { CppTypes element = mangleType.ElementType; IEnumerable <CppModifiers> modifiers = mangleType.Modifiers; StringBuilder code = new StringBuilder(); var ptrOrRef = For.AnyInputIn(CppModifiers.Pointer, CppModifiers.Reference); var modifierCode = modifiers.Reverse().Transform( For.AnyInputIn(CppModifiers.Pointer, CppModifiers.Array).Emit("P"), For.AnyInputIn(CppModifiers.Reference).Emit("R"), // Itanium mangled names do not include const or volatile unless // they modify the type pointed to by pointer or reference. Choose.TopOne( For.AllInputsIn(CppModifiers.Volatile, CppModifiers.Const).InAnyOrder().After(ptrOrRef).Emit("VK"), For.AnyInputIn(CppModifiers.Volatile).After(ptrOrRef).Emit("V"), For.AnyInputIn(CppModifiers.Const).After(ptrOrRef).Emit("K") ) ); code.Append(string.Join(string.Empty, modifierCode.ToArray())); switch (element) { case CppTypes.Int: code.Append(modifiers.Transform( For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder().Emit('t'), For.AnyInputIn(CppModifiers.Short).Emit('s'), For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Long, CppModifiers.Long).InAnyOrder().Emit('y'), For.AllInputsIn(CppModifiers.Long, CppModifiers.Long).InAnyOrder().Emit('x'), For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Long).InAnyOrder().Emit('m'), For.AnyInputIn(CppModifiers.Long).Emit('l'), For.AnyInputIn(CppModifiers.Unsigned).Emit('j') ).DefaultIfEmpty('i').ToArray()); break; case CppTypes.Bool: code.Append('b'); break; case CppTypes.Char: if (modifiers.Contains(CppModifiers.Signed)) { code.Append('a'); } else if (modifiers.Contains(CppModifiers.Unsigned)) { code.Append('h'); } else { code.Append('c'); } break; case CppTypes.Float: code.Append('f'); break; case CppTypes.Double: if (modifiers.Contains(CppModifiers.Long)) { code.Append('e'); } else { code.Append('d'); } break; case CppTypes.Class: case CppTypes.Struct: case CppTypes.Union: case CppTypes.Enum: if (mangleType.Namespaces != null) { code.Append('N'); foreach (var ns in mangleType.Namespaces) { code.Append(GetIdentifier(compressMap, ns)); } } code.Append(GetIdentifier(compressMap, mangleType.ElementTypeName)); if (mangleType.Namespaces != null) { code.Append('E'); } break; } return(code.ToString()); }
public virtual string GetTypeCode(CppType mangleType, BackReferenceList backReferences) { CppTypes element = mangleType.ElementType; IEnumerable <CppModifiers> modifiers = mangleType.Modifiers; StringBuilder code = new StringBuilder(); var ptr = For.AnyInputIn(CppModifiers.Pointer); var ptrRefOrArray = For.AnyInputIn(CppModifiers.Pointer, CppModifiers.Reference, CppModifiers.Array); var modifierCode = modifiers.Reverse().Transform( Choose.TopOne( For.AllInputsIn(CppModifiers.Const, CppModifiers.Volatile).InAnyOrder().After(ptrRefOrArray).Emit('D'), For.AnyInputIn(CppModifiers.Const).After(ptrRefOrArray).Emit('B'), For.AnyInputIn(CppModifiers.Volatile).After(ptrRefOrArray).Emit('C'), For.AnyInput <CppModifiers> ().After(ptrRefOrArray).Emit('A') ), For.AnyInputIn(CppModifiers.Array).Emit('Q'), For.AnyInputIn(CppModifiers.Reference).Emit('A'), Choose.TopOne( ptr.After().AllInputsIn(CppModifiers.Const, CppModifiers.Volatile).InAnyOrder().Emit('S'), ptr.After().AnyInputIn(CppModifiers.Const).Emit('Q'), ptr.After().AnyInputIn(CppModifiers.Volatile).Emit('R'), ptr.Emit('P') ), ptrRefOrArray.AtEnd().Emit('A') ); code.Append(modifierCode.ToArray()); // Type codes taken from http://www.kegel.com/mangle.html#operators switch (element) { case CppTypes.Void: code.Append('X'); break; case CppTypes.Int: code.Append(modifiers.Transform(Choose.TopOne( For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder().Emit('G'), For.AllInputsIn(CppModifiers.Short).InAnyOrder().Emit('F'), For.AllInputsIn(CppModifiers.Unsigned, CppModifiers.Long).InAnyOrder().Emit('K'), For.AllInputsIn(CppModifiers.Long).InAnyOrder().Emit('J'), For.AllInputsIn(CppModifiers.Unsigned).InAnyOrder().Emit('I') )).DefaultIfEmpty('H').ToArray()); break; case CppTypes.Float: code.Append('M'); break; case CppTypes.Double: code.Append(modifiers.Transform( For.AllInputsIn(CppModifiers.Long).InAnyOrder().Emit('O') ).DefaultIfEmpty('N').ToArray()); break; case CppTypes.Char: code.Append(modifiers.Transform(Choose.TopOne( For.AllInputsIn(CppModifiers.Unsigned).InAnyOrder().Emit('E'), For.AllInputsIn(CppModifiers.Signed).InAnyOrder().Emit('C') )).DefaultIfEmpty('D').ToArray()); break; case CppTypes.Class: code.Append('V'); code.Append(GetTypeNameWithBackReferences(mangleType, backReferences)); code.Append("@"); break; case CppTypes.Struct: code.Append('U'); code.Append(GetTypeNameWithBackReferences(mangleType, backReferences)); code.Append("@"); break; case CppTypes.Union: code.Append('T'); code.Append(GetTypeNameWithBackReferences(mangleType, backReferences)); code.Append("@"); break; case CppTypes.Enum: code.Append("W4"); code.Append(GetTypeNameWithBackReferences(mangleType, backReferences)); code.Append("@"); break; case CppTypes.Bool: code.Append("_N"); break; } return(code.ToString()); }