예제 #1
0
        public ExternStatic(TaggedSymbol taggedSymbol, string name, int offset)
        {
            _taggedSymbol = taggedSymbol;
            _name         = name;
            _offset       = offset;

            if (taggedSymbol.Type != SymbolType.External && taggedSymbol.Type != SymbolType.Static)
            {
                throw new ArgumentException($"Symbol type must be {SymbolType.External} or {SymbolType.Static}",
                                            nameof(taggedSymbol));
            }
        }
예제 #2
0
        public CompoundMember(TypedValue typedValue, BinaryReader reader, bool isArray)
        {
            MemberType = reader.ReadTaggedSymbol(isArray);
            _name      = reader.ReadPascalString();
            TypedValue = typedValue;

            if (MemberType.Type != SymbolType.Bitfield &&
                MemberType.Type != SymbolType.StructMember &&
                MemberType.Type != SymbolType.UnionMember &&
                MemberType.Type != SymbolType.EndOfStruct)
            {
                throw new Exception($"Unexpected {nameof(SymbolType)} {MemberType.Type}");
            }
        }
예제 #3
0
        private void AddTypedef(string name, TaggedSymbol taggedSymbol)
        {
            if (name.IsFake())
            {
                throw new Exception($"Found fake typedef name {name}");
            }

            if (taggedSymbol.IsFake && ComplexTypes.ContainsKey(taggedSymbol.Tag))
            {
                // found a typedef for a fake symbol, e.g. typedef struct .123fake {} FOO
                ComplexTypes[taggedSymbol.Tag].Typedefs.Add(name, taggedSymbol);
            }

            if (_typedefs.TryGetValue(name, out var already))
            {
                if (taggedSymbol.Equals(already))
                {
                    return;
                }

                var writer = new IndentedTextWriter(Console.Out);
                writer.WriteLine($"WARNING: Non-uniform definitions of typedef {name}");
                writer.WriteLine("This is the definition already present:");
                writer.Indent++;
                writer.WriteLine(already.ToString());
                writer.WriteLine(already.AsCode(name));
                ComplexTypes[already.Tag].Dump(writer, false);

                writer.Indent--;
                writer.WriteLine("This is the new definition:");
                writer.Indent++;
                writer.WriteLine(taggedSymbol.ToString());
                writer.WriteLine(taggedSymbol.AsCode(name));
                ComplexTypes[taggedSymbol.Tag].Dump(writer, false);

                writer.Indent--;

                throw new Exception($"Non-uniform definition of typedef {name}");
            }

            _typedefs.Add(name, taggedSymbol);
        }
예제 #4
0
        public string ReverseTypedef(TaggedSymbol taggedSymbol, out int droppedDerived)
        {
            droppedDerived = 0;

            if (!ComplexTypes.TryGetValue(taggedSymbol.Tag, out var complexType))
            {
                return(null);
            }

            var typedefs = complexType.Typedefs
                           .Where(_ => _.Value.Equals(taggedSymbol))
                           .ToList();

            if (typedefs.Count >= 1)
            {
                return(typedefs[0].Key);
            }

            /*
             * Now the fun part... resolving
             *   typedef struct .fake123 {} FOO;
             *   struct .fake123* foo;
             * to
             *   FOO* foo;
             */

            for (var i = 0; i <= DerivedTypeDef.MaxDerivedTypes; ++i)
            {
                droppedDerived = i;
                var partialTypedefs = complexType.Typedefs
                                      .Where(_ => _.Value.IsPartOf(taggedSymbol, i))
                                      .ToList();
                if (partialTypedefs.Count >= 1)
                {
                    return(partialTypedefs[0].Key);
                }
            }

            droppedDerived = 0;
            return(null);
        }
예제 #5
0
        public string AsCode(string name, TaggedSymbol taggedSymbol, bool onlyDecorated = false)
        {
            var dimIdx = 0;

            string cType;

            if (taggedSymbol.IsResolvedTypedef)
            {
                cType = taggedSymbol.InnerCode ?? taggedSymbol.Tag;
            }
            else
            {
                switch (Type)
                {
                case PrimitiveType.StructDef:
                    Debug.Assert(!string.IsNullOrEmpty(taggedSymbol.Tag));
                    cType = taggedSymbol.InnerCode ?? (taggedSymbol.IsResolvedTypedef
                                    ? taggedSymbol.Tag
                                    : $"struct {taggedSymbol.Tag}");
                    break;

                case PrimitiveType.UnionDef:
                    Debug.Assert(!string.IsNullOrEmpty(taggedSymbol.Tag));
                    cType = taggedSymbol.InnerCode ?? (taggedSymbol.IsResolvedTypedef
                                    ? taggedSymbol.Tag
                                    : $"union {taggedSymbol.Tag}");
                    break;

                case PrimitiveType.EnumDef:
                    Debug.Assert(!string.IsNullOrEmpty(taggedSymbol.Tag));
                    cType = taggedSymbol.InnerCode ?? (taggedSymbol.IsResolvedTypedef
                                    ? taggedSymbol.Tag
                                    : $"enum {taggedSymbol.Tag}");
                    break;

                case PrimitiveType.Char:
                    cType = "char";
                    break;

                case PrimitiveType.Short:
                    cType = "short";
                    break;

                case PrimitiveType.Int:
                    cType = "int";
                    break;

                case PrimitiveType.Long:
                    cType = "long";
                    break;

                case PrimitiveType.Float:
                    cType = "float";
                    break;

                case PrimitiveType.Double:
                    cType = "double";
                    break;

                case PrimitiveType.UChar:
                    cType = "unsigned char";
                    break;

                case PrimitiveType.UShort:
                    cType = "unsigned short";
                    break;

                case PrimitiveType.UInt:
                    cType = "unsigned int";
                    break;

                case PrimitiveType.ULong:
                    cType = "unsigned long";
                    break;

                case PrimitiveType.Void:
                    cType = "void";
                    break;

                case PrimitiveType.Null:
                    cType = "__NULL__";
                    logger.Warn($"Found Null primitive type for symbol {name}");
                    break;

                default:
                    throw new Exception($"Unexpected base type {Type}");
                }
            }

            var prevPrecedence = int.MaxValue;
            var decorated      = name;

            foreach (var derivedType in _derivedTypes)
            {
                switch (derivedType)
                {
                case DerivedType.Array:
                    Debug.Assert(decorated != null);

                    if (prevPrecedence < 2)
                    {
                        decorated = $"({decorated})";
                    }

                    decorated += $"[{taggedSymbol.Extents[dimIdx]}]";
                    ++dimIdx;
                    prevPrecedence = 2;
                    break;

                case DerivedType.FunctionReturnType:
                    if (prevPrecedence < 2)
                    {
                        decorated = $"({decorated})";
                    }

                    decorated     += "()";
                    prevPrecedence = 2;

                    break;

                case DerivedType.Pointer:
                    if (prevPrecedence < 2)
                    {
                        decorated = $"({decorated})";
                    }

                    decorated      = $"*{decorated}";
                    prevPrecedence = 3;
                    break;

                default:
                    throw new Exception($"Unexpected derived type {derivedType}");
                }
            }

            return(onlyDecorated ? decorated : $"{cType} {decorated}");
        }