コード例 #1
0
        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());
        }
コード例 #2
0
ファイル: MsvcAbi.cs プロジェクト: zhoulihe1981/cxxi
        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());
        }
コード例 #3
0
ファイル: ItaniumAbi.cs プロジェクト: zhoulihe1981/cxxi
        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());
        }
コード例 #4
0
ファイル: MsvcAbi.cs プロジェクト: kthompson/cxxi
        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());
        }