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 */ }
/// <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; } } }
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); }
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)); }
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())); }