예제 #1
0
    /*
     * Merge two type sets into an aggregate set. If one of the sets
     * is a subset of the other, then that other subset is returned;
     * if the two sets are equal, then the ss1 instance is returned.
     *
     * If merging is not possible (incompatible basic types), then
     * null is returned, and err is set to an appropriate error
     * message. Otherwise, the merged type is returned, and err is
     * set to null.
     */
    internal static CCTypeSet MergeNF(CCTypeSet ss1, CCTypeSet ss2,
                                      out string err)
    {
        err = null;
        if (ss2.IsSubsetOf(ss1))
        {
            return(ss1);
        }
        if (ss1.IsSubsetOf(ss2))
        {
            return(ss2);
        }

        /*
         * Handling of restricted types relies on the following
         * features:
         *
         *  - A CCTypeSet that contains a restricted type can
         *    only contain that restricted type, none other.
         *
         *  - Restricted types cannot have allocation nodes,
         *    variants, or be std::type.
         *
         *  - The tests with IsSubsetOf() above have already
         *    ruled out the case of two identical restricted types.
         */
        if (ss1.types.Count == 1 && ss2.types.Count == 1)
        {
            CCType ct1 = ss1.types.Min;
            CCType ct2 = ss2.types.Min;
            if (ct1.xType.IsRestricted || ct2.xType.IsRestricted)
            {
                err = string.Format("forbidden type merging between {0} and {1}", ct1, ct2);
                return(null);
            }
        }

        CCTypeSet ss3 = new CCTypeSet();

        foreach (CCType t in ss1.types)
        {
            ss3.types.Add(t);
            ss3.xTypes.Add(t.xType);
        }
        foreach (CCType t in ss2.types)
        {
            ss3.types.Add(t);
            ss3.xTypes.Add(t.xType);
        }
        return(ss3);
    }
예제 #2
0
    internal CCLocals Set(int index, CCTypeSet cts)
    {
        CCTypeSet octs = locals[index];

        if (!cts.IsSubsetOf(octs))
        {
            CCLocals r = new CCLocals(locals.Length);
            Array.Copy(locals, 0, r.locals, 0, locals.Length);
            r.locals[index] = cts;
            return(r);
        }
        else
        {
            return(this);
        }
    }
예제 #3
0
    internal static CCLocals MergeNF(
        CCLocals l1, CCLocals l2, out string err)
    {
        err = null;
        if (object.ReferenceEquals(l1, l2))
        {
            return(l1);
        }
        int n = l1.locals.Length;

        if (n != l2.locals.Length)
        {
            err = string.Format("internal error: mismatch on number of locals ({0} / {1})", n, l2.locals.Length);
            return(null);
        }

        /*
         * Merge entries one by one. The destination is lazily
         * updated to avoid allocation when not needed.
         */
        bool r1ok = true, r2ok = true;

        CCTypeSet[] nlocals = null;
        for (int i = 0; i < n; i++)
        {
            CCTypeSet cts1 = l1.locals[i];
            CCTypeSet cts2 = l2.locals[i];
            if (cts1.Equals(cts2))
            {
                if (nlocals != null)
                {
                    nlocals[i] = cts1;
                }
            }
            else if (cts1.IsSubsetOf(cts2))
            {
                r1ok = false;
                if (r2ok)
                {
                    continue;
                }
                if (nlocals != null)
                {
                    nlocals[i] = cts2;
                }
            }
            else if (cts2.IsSubsetOf(cts1))
            {
                r2ok = false;
                if (r1ok)
                {
                    continue;
                }
                if (nlocals != null)
                {
                    nlocals[i] = cts1;
                }
            }
            else
            {
                if (nlocals == null)
                {
                    r1ok    = false;
                    r2ok    = false;
                    nlocals = new CCTypeSet[n];
                    Array.Copy(l1.locals, 0, nlocals, 0, i);
                }
                CCTypeSet cts = CCTypeSet.MergeNF(
                    cts1, cts2, out err);
                if (cts == null)
                {
                    return(null);
                }
                nlocals[i] = cts;
            }
        }

        if (r1ok)
        {
            return(l1);
        }
        if (r2ok)
        {
            return(l2);
        }
        return(new CCLocals(nlocals));
    }