コード例 #1
0
        private static bool IsBoundedVector(Type type)
        {
            ArrayType?at = type as ArrayType;

            if (at != null)
            {
                return(at.GetEffectiveRank() == 1);
            }
            return(type.ToString().EndsWith("[*]", StringComparison.Ordinal)); /*Super uggly hack, SR doesn't allow one to query for it */
        }
コード例 #2
0
        /// <summary>
        /// Merges staggered arrays in a structure into a single array.
        /// </summary>
        /// <param name="s"></param>
        public void MergeStaggeredArrays(StructureType s)
        {
            ArrayType?       arrMerged = null;
            StructureType?   strMerged = null;
            EquivalenceClass?eqMerged  = null;
            int offset = 0;

            for (int i = 0; i < s.Fields.Count; ++i)
            {
                if (!(s.Fields[i].DataType is ArrayType a))
                {
                    continue;
                }
                EquivalenceClass?eqElem = a.ElementType as EquivalenceClass;
                StructureType?   strElem;
                if (eqElem == null)
                {
                    strElem = a.ElementType as StructureType;
                }
                else
                {
                    strElem = eqElem.DataType as StructureType;
                }
                if (strElem == null)
                {
                    continue;
                }

                if (StructuresOverlap(strMerged, offset, strElem, s.Fields[i].Offset))
                {
                    strMerged = MergeOffsetStructures(strMerged !, offset, strElem, s.Fields[i].Offset);
                    if (eqMerged != null)
                    {
                        eqMerged.DataType = strMerged;
                    }
                    else
                    {
                        arrMerged !.ElementType = strMerged;
                    }
                    s.Fields.RemoveAt(i);
                    Changed = true;
                    --i;
                }
                else
                {
                    arrMerged = a;
                    strMerged = strElem;
                    eqMerged  = eqElem;
                    offset    = s.Fields[i].Offset;
                }
            }
        }
コード例 #3
0
        private bool DoAreCompatible(DataType a, DataType b, int depth)
        {
            if (a == null || b == null)
            {
                return(false);
            }

            if (depth > 20)
            {
                trace.Error("Way too deep");     //$BUG: discover why datatypes recurse so deep.
                return(true);
            }

            PrimitiveType?pa = a as PrimitiveType;
            PrimitiveType?pb = b as PrimitiveType;

            if (pa != null && pb != null)
            {
                if (pa.Size != pb.Size)
                {
                    return(false);
                }
                return((pa.Domain & pb.Domain) != 0);
            }

            TypeReference?tra = a as TypeReference;
            TypeReference?trb = b as TypeReference;

            if (tra != null && trb != null)
            {
                return(tra == trb);
            }
            if (tra != null)
            {
                return(AreCompatible(tra.Referent, b, ++depth));
            }
            if (trb != null)
            {
                return(AreCompatible(a, trb.Referent, ++depth));
            }

            TypeVariable?tva = a as TypeVariable;
            TypeVariable?tvb = b as TypeVariable;

            if (tva != null && tvb != null)
            {
                return(tva.Number == tvb.Number);
            }

            EquivalenceClass?eqA = a as EquivalenceClass;
            EquivalenceClass?eqB = b as EquivalenceClass;

            if (eqA != null && eqB != null)
            {
                return(eqA.Number == eqB.Number);
            }

            Pointer?ptrA = a as Pointer;
            Pointer?ptrB = b as Pointer;

            if (ptrA != null)
            {
                return(IsCompatibleWithPointer(ptrA, b, ++depth));
            }
            if (ptrB != null)
            {
                return(IsCompatibleWithPointer(ptrB, a, ++depth));
            }

            MemberPointer?mpA = a as MemberPointer;
            MemberPointer?mpB = b as MemberPointer;

            if (mpA != null)
            {
                return(IsCompatibleWithMemberPointer(mpA, b, ++depth));
            }
            if (mpB != null)
            {
                return(IsCompatibleWithMemberPointer(mpB, a, ++depth));
            }

            StructureType?sa = a as StructureType;
            StructureType?sb = b as StructureType;

            if (sa != null && sb != null)
            {
                return(AreCompatible(sa, sb));
            }

            ArrayType?aa = a as ArrayType;
            ArrayType?ab = b as ArrayType;

            if (aa != null && ab != null)
            {
                return(AreCompatible(aa.ElementType, ab.ElementType, ++depth));
            }

            UnionType?ua = a as UnionType;
            UnionType?ub = b as UnionType;

            if (ua != null && ub != null)
            {
                return(true);
            }

            FunctionType?fa = a as FunctionType;
            FunctionType?fb = b as FunctionType;

            if (fa != null && fb != null)
            {
                if (fa.ParametersValid != fb.ParametersValid)
                {
                    return(false);
                }
                return(fa.Parameters !.Length == fb.Parameters !.Length);
            }

            CodeType?ca = a as CodeType;
            CodeType?cb = a as CodeType;

            if (ca != null && cb != null)
            {
                return(true);
            }
            if (a is UnknownType unkA)
            {
                if (unkA.Size == 0 || a.Size == b.Size)
                {
                    return(true);
                }
            }
            if (b is UnknownType unkB)
            {
                if (unkB.Size == 0 || a.Size == b.Size)
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #4
0
        private DataType?UnifyInternal(DataType?a, DataType?b)
        {
            if (a == null)
            {
                return(b);
            }
            if (b == null)
            {
                return(a);
            }

            if (a == b)
            {
                return(a);
            }

            if (a is UnknownType)
            {
                if (a.Size == 0 || a.Size == b.Size)
                {
                    return(b);
                }
            }
            if (b is UnknownType)
            {
                if (b.Size == 0 || a.Size == b.Size)
                {
                    return(a);
                }
            }

            if (a is VoidType)
            {
                return(b);
            }
            if (b is VoidType)
            {
                return(a);
            }

            UnionType?ua = a as UnionType;
            UnionType?ub = b as UnionType;

            if (ua != null && ub != null)
            {
                UnionType u2 = UnifyUnions(ua, ub);
                return(u2.Simplify());
            }
            if (ua != null)
            {
                UnifyIntoUnion(ua, b);
                return(ua.Simplify());
            }
            if (ub != null)
            {
                UnifyIntoUnion(ub, a);
                return(ub.Simplify());
            }

            PrimitiveType?pa = a as PrimitiveType;
            PrimitiveType?pb = b as PrimitiveType;

            if (pa != null && pb != null)
            {
                if (pa == pb)
                {
                    return(pa);
                }

                return(UnifyPrimitives(pa, pb));
            }

            TypeVariable?tA = a as TypeVariable;
            TypeVariable?tB = b as TypeVariable;

            if (tA != null && tB != null)
            {
                return(UnifyTypeVariables(tA, tB));
            }

            TypeReference?trA = a as TypeReference;
            TypeReference?trB = b as TypeReference;

            if (trA != null && trB != null)
            {
                if (trA == trB)
                {
                    return(trA);
                }
                else
                {
                    return(MakeUnion(a, b));
                }
            }
            if (trA != null)
            {
                if (AreCompatible(trA.Referent, b))
                {
                    return(new TypeReference(trA.Name, UnifyInternal(trA.Referent, b) !));
                }
            }
            if (trB != null)
            {
                if (AreCompatible(a, trB.Referent))
                {
                    return(new TypeReference(trB.Name, UnifyInternal(trB.Referent, a) !));
                }
            }

            EquivalenceClass?eqA = a as EquivalenceClass;
            EquivalenceClass?eqB = b as EquivalenceClass;

            if (eqA != null && eqB != null)
            {
                if (eqA.Number == eqB.Number)
                {
                    return(eqA);
                }
                else
                {
                    return(MakeUnion(eqA, eqB));
                }
            }

            Pointer?ptrA = a as Pointer;
            Pointer?ptrB = b as Pointer;

            if (ptrA != null && ptrB != null)
            {
                DataType dt = UnifyInternal(ptrA.Pointee, ptrB.Pointee) !;
                return(new Pointer(dt, Math.Max(ptrA.BitSize, ptrB.BitSize)));
            }
            if (ptrA != null)
            {
                var dt = UnifyPointer(ptrA, b);
                if (dt != null)
                {
                    return(dt);
                }
            }
            if (ptrB != null)
            {
                var dt = UnifyPointer(ptrB, a);
                if (dt != null)
                {
                    return(dt);
                }
            }

            MemberPointer?mpA = a as MemberPointer;
            MemberPointer?mpB = b as MemberPointer;

            if (mpA != null && mpB != null)
            {
                DataType baseType = UnifyInternal(mpA.BasePointer, mpB.BasePointer) !;
                DataType pointee  = UnifyInternal(mpA.Pointee, mpB.Pointee) !;
                return(new MemberPointer(baseType, pointee, mpB.BitSize));
            }
            if (mpA != null)
            {
                var dt = UnifyMemberPointer(mpA, b);
                if (dt != null)
                {
                    return(dt);
                }
            }
            if (mpB != null)
            {
                var dt = UnifyMemberPointer(mpB, a);
                if (dt != null)
                {
                    return(dt);
                }
            }

            FunctionType?funA = a as FunctionType;
            FunctionType?funB = b as FunctionType;

            if (funA != null && funB != null)
            {
                return(UnifyFunctions(funA, funB));
            }
            if (funA != null && b is CodeType)
            {
                return(funA);
            }
            if (funB != null && a is CodeType)
            {
                return(funB);
            }

            ArrayType?arrA = a as ArrayType;
            ArrayType?arrB = b as ArrayType;

            if (arrA != null && arrB != null)
            {
                return(UnifyArrays(arrA, arrB));
            }
            if (arrA != null && arrA.ElementType.Size >= b.Size)
            {
                arrA.ElementType = Unify(arrA.ElementType, b) !;
                return(arrA);
            }
            if (arrB != null && arrB.ElementType.Size >= a.Size)
            {
                arrB.ElementType = Unify(arrB.ElementType, a) !;
                return(arrB);
            }

            StructureType?strA = a as StructureType;
            StructureType?strB = b as StructureType;

            if (strA != null && strB != null)
            {
                return(UnifyStructures(strA, strB));
            }
            if (strA != null && (strA.Size == 0 || strA.Size >= b.Size))
            {
                MergeIntoStructure(b, strA);
                return(strA);
            }
            if (strB != null && (strB.Size == 0 || strB.Size >= a.Size))
            {
                MergeIntoStructure(a, strB);
                return(strB);
            }
            if (strA != null || strB != null)
            {
                return(MakeUnion(a, b));
            }
            CodeType?ca = a as CodeType;
            CodeType?cb = b as CodeType;

            if (ca != null && cb != null)
            {
                return(ca);
            }
            if (tA != null)
            {
                return(UnifyTypeVariable(tA, b));
            }
            if (tB != null)
            {
                return(UnifyTypeVariable(tB, a));
            }
            return(MakeUnion(a, b));
        }
コード例 #5
0
        public int CompareInternal(DataType x, DataType y, int count)
        {
            if (count > 20)
            {
                Debug.WriteLine("Way too deep");     //$BUG: discover why datatypes recurse so deep.
                return(0);
            }
            int prioX = x.Accept(this);
            int prioY = y.Accept(this);
            int dPrio = prioX - prioY;

            if (dPrio != 0)
            {
                return(dPrio);
            }

            if (x is VoidType)
            {
                return(0);
            }

            if (x is UnknownType unkX && y is UnknownType unkY)
            {
                return(unkX.Size.CompareTo(unkY.Size));
            }
            if (x is UnknownType)
            {
                return(-1);
            }
            if (y is UnknownType)
            {
                return(1);
            }

            PrimitiveType?ix = x as PrimitiveType;
            PrimitiveType?iy = y as PrimitiveType;

            if (ix != null && iy != null)
            {
                return(ix.Compare(iy));
            }
            if (ix != null)
            {
                return(-1);
            }
            if (iy != null)
            {
                return(1);
            }

            if (x is EnumType || y is EnumType)
            {
                throw new NotImplementedException();
            }

            CodeType?cx = x as CodeType;
            CodeType?cy = y as CodeType;

            if (cx != null && cy != null)
            {
                return(0);
            }
            if (cx != null)
            {
                return(-1);
            }
            if (cy != null)
            {
                return(1);
            }

            TypeVariable?tx = x as TypeVariable;
            TypeVariable?ty = y as TypeVariable;

            if (tx != null && ty != null)
            {
                return(tx.Number - ty.Number);
            }

            TypeReference?tr_x = x as TypeReference;
            TypeReference?tr_y = y as TypeReference;

            if (tr_x != null && tr_y != null)
            {
                return(StringComparer.InvariantCulture.Compare(tr_x.Name, tr_y.Name));
            }

            EquivalenceClass?ex = x as EquivalenceClass;
            EquivalenceClass?ey = y as EquivalenceClass;

            if (ex != null && ey != null)
            {
                return(ex.Number - ey.Number);
            }

            Pointer?ptrX = x as Pointer;
            Pointer?ptrY = y as Pointer;

            if (ptrX != null && ptrY != null)
            {
                return(Compare(ptrX.Pointee, ptrY.Pointee, ++count));
            }

            MemberPointer?mX = x as MemberPointer;
            MemberPointer?mY = y as MemberPointer;

            if (mX != null && mY != null)
            {
                int d = Compare(mX.BasePointer, mY.BasePointer, ++count);
                if (d != 0)
                {
                    return(d);
                }
                return(Compare(mX.Pointee, mY.Pointee, ++count));
            }

            ReferenceTo?rX = x as ReferenceTo;
            ReferenceTo?rY = y as ReferenceTo;

            if (rX != null && rY != null)
            {
                return(Compare(rX.Referent, rY.Referent, ++count));
            }

            StructureType?sX = x as StructureType;
            StructureType?sY = y as StructureType;

            if (sX != null && sY != null)
            {
                return(Compare(sX, sY, ++count));
            }

            UnionType?ux = x as UnionType;
            UnionType?uy = y as UnionType;

            if (ux != null && uy != null)
            {
                return(Compare(ux, uy, ++count));
            }
            ArrayType?ax = x as ArrayType;
            ArrayType?ay = y as ArrayType;

            if (ax != null && ay != null)
            {
                return(Compare(ax, ay, ++count));
            }

            StringType?strX = x as StringType;
            StringType?strY = y as StringType;

            if (strX != null && strY != null)
            {
                return(Compare(strX, strY, ++count));
            }

            FunctionType?fnX = x as FunctionType;
            FunctionType?fnY = y as FunctionType;

            if (fnX != null && fnY != null)
            {
                return(Compare(fnX, fnY, ++count));
            }
            throw new NotImplementedException(string.Format("NYI: comparison between {0} and {1}", x.GetType(), y.GetType()));
        }