예제 #1
0
            public Value BuildBr(Block block, AST.Node contextNode)
            {
                var result = new Value(Op.Br, null, block);

                AddOp(result, contextNode: contextNode);
                return(result);
            }
예제 #2
0
            public Value BuildRet(Value ret, AST.Node contextNode)
            {
                var result = new Value(Op.Ret, ret.type, ret);

                AddOp(result, contextNode: contextNode);
                return(result);
            }
예제 #3
0
            public Value BuildRetVoid(AST.Node contextNode)
            {
                var result = new Value(Op.Ret, Const.void_t);

                AddOp(result, contextNode: contextNode);
                return(result);
            }
예제 #4
0
            public Value BuildExtractValue(Value v, AST.Node contextNode, string name = null, params Value[] indices)
            {
                Debug.Assert(indices != null && indices.Length > 0);
                var result = new Value(Op.ExtractValue, null, v);

                result.args.AddRange(indices);

                Debug.Assert(indices != null && indices.Length > 0);
                Debug.Assert(indices[0].type.kind == TypeKind.Integer);
                SSAType resultType = v.type;

                for (int i = 0; i < indices.Length; ++i)
                {
                    var idx = indices[i];
                    Debug.Assert(idx.type.kind == TypeKind.Integer);
                    if (resultType.kind == TypeKind.Array)
                    {
                        resultType = ((ArrayType)resultType).elementType;
                    }
                    else if (resultType.kind == TypeKind.Struct)
                    {
                        Debug.Assert(idx.isConst);
                        var elementIdx = (int)(idx as ConstInt).data;
                        var st         = (StructType)resultType;
                        resultType = st.elementTypes[elementIdx];
                    }
                }
                result.type    = resultType;
                result.isConst = v.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #5
0
            public Value BuildCall(Value fun, AST.Node contextNode, string name = null, params Value[] args)
            {
                Debug.Assert(fun.type.kind == TypeKind.Pointer);
                var ft = (fun.type as PointerType).elementType as FunctionType;

                Debug.Assert(ft != null);

                var result = new Value(Op.Call, ft, fun);

                if (args != null && args.Length > 0)
                {
                    result.args.AddRange(args);
                }
                result.type = ft.returnType;
                if (result.type.kind != TypeKind.Void)
                {
                    AddOp(result, name, contextNode: contextNode);
                }
                else
                {
                    AddOp(result, contextNode: contextNode);
                }

                return(result);
            }
예제 #6
0
            public Value BuildCondBr(Value cond, Block ifTrue, Block ifFalse, AST.Node contextNode)
            {
                Debug.Assert(SSAType.IsBoolType(cond.type));
                var result = new Value(Op.Br, null, cond, ifTrue, ifFalse);

                AddOp(result, contextNode: contextNode);
                return(result);
            }
예제 #7
0
            public Value BuildBitCast(Value v, SSAType dest, AST.Node contextNode, string name = null)
            {
                var result = new Value(Op.BitCast, dest, v);

                result.isConst = v.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #8
0
            public GetElementPtr BuildGEP(Value ptr, AST.Node contextNode, string name = null, bool inBounds = false, params Value[] indices)
            {
                var result = new GetElementPtr(ptr, inBounds, indices);

                result.isConst = ptr.isConst && indices.All(idx => idx.isConst);
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #9
0
            public GetElementPtr BuildStructGEP(Value structPointer, int idx, AST.Node contextNode, string name = null)
            {
                var result = new GetElementPtr(structPointer, true, zero_i32_v, new ConstInt(i32_t, (ulong)idx));

                result.isConst = structPointer.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #10
0
            public Value BuildNot(Value v, AST.Node contextNode, string name = null)
            {
                var result = new Value(Op.Not, v.type, v);

                result.isConst = v.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #11
0
            public ICmp BuildICmp(Value left, Value right, IcmpType icmpType, AST.Node contextNode, string name = null)
            {
                var result = new ICmp(left, right, icmpType, name);

                result.isConst = left.isConst && right.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #12
0
            public Value BuildFRem(Value left, Value right, AST.Node contextNode, string name = null)
            {
                var result = new Value(Op.FRem, left.type, left, right);

                result.isConst = left.isConst && right.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #13
0
            public Value BuildFCmp(Value left, Value right, FcmpType fcmpType, AST.Node contextNode, string name = null)
            {
                var result = new FCmp(left, right, fcmpType, name);

                result.isConst = left.isConst && right.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #14
0
            public Value BuildPtrToInt(Value v, SSAType integerType, AST.Node contextNode, string name = null)
            {
                var result = new Value(Op.PtrToInt, integerType, v);

                result.isConst = v.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #15
0
            public Value BuildIntToPtr(Value v, SSAType pointerType, AST.Node contextNode, string name = null)
            {
                var result = new Value(Op.IntToPtr, pointerType, v);

                result.isConst = v.isConst;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #16
0
            public Value BuildArrayAlloca(SSAType t, Value size, AST.Node contextNode, string name = null)
            {
                var result = new Value(Op.Alloca, new PointerType(t), size);

                result.alignment = 16;
                Debug.Assert(size.type.kind == TypeKind.Integer);
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #17
0
            public Value BuildSizeOf(SSAType t, AST.Node contextNode, string name = null)
            {
                var np     = new ConstPtr(new PointerType(t), 0);
                var size   = BuildGEP(np, contextNode, "size_of_trick", false, one_i32_v);
                var result = BuildPtrToInt(size, Const.mm_t, contextNode, name);

                Debug.Assert(result.isConst);
                return(result);
            }
예제 #18
0
            public Value BuildGlobalStringPtr(string str, AST.Node contextNode, string name = null)
            {
                var gs = new GlobalStringPtr(str);

                AddOpGlobal(gs, name, contextNode: contextNode);
                var result = BuildBitCast(gs, ptr_t, contextNode);

                Debug.Assert(result.isConst);
                return(result);
            }
예제 #19
0
            void AddOpGlobal(Value v, string name, AST.Node contextNode = null)
            {
                Debug.Assert(v is GlobalVariable || v is GlobalStringPtr || v is Function);

                if (name != null)
                {
                    v.name = context.RequestGlobalName(name);
                }
                mod.globals.args.Add(v);
                v.debugContextNode = contextNode;
            }
예제 #20
0
            public Value BuildAlloca(SSAType t, AST.Node contextNode, string name = null, int align = 0)
            {
                if (align > 32)
                {
                    align = 32;
                }
                var result = new Value(Op.Alloca, new PointerType(t));

                result.alignment = align;
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #21
0
            public GlobalVariable AddGlobal(SSAType t, AST.Node contextNode, string name = null, bool isConst = false, int align = 0)
            {
                if (align > 16)
                {
                    align = 16;
                }
                var result = new GlobalVariable(t, isConst);

                result.alignment = align;

                AddOpGlobal(result, name, contextNode: contextNode);
                return(result);
            }
예제 #22
0
            public Value BuildMemCpy(Value destPtr, Value srcPtr, Value count, AST.Node contextNode, bool isVolatile = false)
            {
                Value isVolatile_v;

                if (isVolatile)
                {
                    isVolatile_v = true_v;
                }
                else
                {
                    isVolatile_v = false_v;
                }
                var result = BuildCall(intrinsic_memcpy, contextNode, "memcpy", destPtr, srcPtr, count, zero_i32_v, isVolatile_v);

                return(result);
            }
예제 #23
0
            public Value BuildStore(Value v, Value ptr, AST.Node contextNode, bool isVolatile = false, int align = 0)
            {
                if (align > 16)
                {
                    align = 16;
                }
                Debug.Assert(ptr.type.kind == TypeKind.Pointer);
                var result = new Value(Op.Store, null, v, ptr);

                result.alignment = align;
                if (isVolatile)
                {
                    result.flags |= SSAFlags.@volatile;
                }
                AddOp(result, contextNode: contextNode);
                return(result);
            }
예제 #24
0
            public Value BuildLoad(Value ptr, AST.Node contextNode, string name = null, bool isVolatile = false, int align = 0)
            {
                if (align > 16)
                {
                    align = 16;
                }
                Debug.Assert(ptr.type.kind == TypeKind.Pointer);
                var pt     = (PointerType)ptr.type;
                var result = new Value(Op.Load, pt.elementType, ptr);

                result.alignment = align;
                if (isVolatile)
                {
                    result.flags |= SSAFlags.@volatile;
                }
                AddOp(result, name, contextNode: contextNode);
                return(result);
            }
예제 #25
0
 void AddOp(Value v, string name = null, Function f = null, AST.Node contextNode = null)
 {
     if (!v.isConst)
     {
         if (name != null)
         {
             v.name = context.RequestLocalName_(name, f);
         }
         context.currentBlock.args.Add(v);
     }
     if (context.callsite == null)
     {
         v.debugContextNode = contextNode;
     }
     else
     {
         v.debugContextNode = context.callsite;
     }
 }
예제 #26
0
    //-----------------------------------------------------------------------------
    // This construct must be inside a loop
    //-----------------------------------------------------------------------------
    public static SymbolErrorException MustBeInsideLoop(AST.Node node)
    {
        string stHint = "?";

        if (node is AST.BreakStatement)
        {
            stHint = "break";
        }
        else if (node is AST.ContinueStatement)
        {
            stHint = "continue";
        }
        else
        {
            Debug.Assert(false, "Illegal type:" + node.GetType());
        }

        return(new SymbolErrorException(
                   Code.cMustBeInsideLoop,
                   node.Location,
                   "'" + stHint + "' must occur inside a control block (do, while, for)"
                   ));
    }
예제 #27
0
    public static AST.Node FindNode(Scope scope, int posZeroBased, int lineZeroBased, string filePath)
    {
        AST.Node FindNodeRec(AST.Node node, int pos, int line)
        {
            if (node.token.filename != filePath)
            {
                return(null);
            }
            if (InsideToken(node.token, pos, line))
            {
                return(node);
            }
            else
            {
                if (node is AST.FieldAccess fa)
                {
                    if (InsideToken(fa.fieldNameToken, pos, line))
                    {
                        return(node);
                    }
                }
                foreach (var child in node.GetChilds())
                {
                    var result = FindNodeRec(child, pos, line);
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }
            return(null);
        }

        AST.Node result = FindNodeRec(scope.owner, posZeroBased + 1, lineZeroBased + 1);
        return(result);
    }
예제 #28
0
파일: TypeAST.cs 프로젝트: chenzuo/blue
 public ArrayInitializer(Node[] list)
 {
     m_list= list;
 }
예제 #29
0
 public Value BuildFNeg(Value v, AST.Node contextNode, string name = null)
 {
     return(BuildFSub(ConstNull(v.type), v, contextNode, name));
 }
예제 #30
0
파일: AST.cs 프로젝트: chenzuo/blue
// Utility to Dump to XML file
    public static void DumpTree(Node root, XmlWriter o)
    {
        o.WriteStartDocument();
        o.WriteStartElement("AST");
        root.Dump(o);
        o.WriteEndElement(); // AST
        o.WriteEndDocument();
        o.Close();
    }
예제 #31
0
 public Value BuildNeg(Value v, AST.Node contextNode, string name = null)
 {
     Debug.Assert(v.type.kind == TypeKind.Integer);
     return(BuildSub(ConstNull(v.type), v, contextNode, name));
 }
예제 #32
0
파일: AST.cs 프로젝트: chenzuo/blue
 // Debugging facility. Dump() spits out XML which can be really tough to read,
 // and it's not clear what it should include.
 // So we have a facility to spit it out as a string.
 static string GetAsSourceString(Node n)
 {
     //System.Text.StringBuilder sb = new System.Text.StringBuilder();    
     //n.ToSource(sb);
     //return sb.ToString();
     return "empty";
 }
예제 #33
0
파일: AST.cs 프로젝트: chenzuo/blue
 public static void DumpSourceToStream(Node n, System.IO.TextWriter t)
 {
     Console.WriteLine("*** Begin Source dump: [");
     
     System.CodeDom.Compiler.IndentedTextWriter i = new 
         System.CodeDom.Compiler.IndentedTextWriter(t, "    ");
     
             
     n.ToSource(i);
     
     Console.WriteLine("] *** End source dump");
     
     i.Close();        
     i = null;
     
 }
예제 #34
0
파일: AST.cs 프로젝트: chenzuo/blue
 // Dump the string to the console.
 public static void DumpSource(Node n)
 {        
     DumpSourceToStream(n, Console.Out);     
 }
예제 #35
0
파일: TypeAST.cs 프로젝트: chenzuo/blue
 // Create an array initializer from the list
 public ArrayInitializer(System.Collections.ArrayList al)
 {
     m_list = new Node[al.Count];
     for(int i = 0; i < m_list.Length; i++)
         m_list[i] = (Node) al[i];
 }
예제 #36
0
 public Phi BuildPhi(SSAType t, AST.Node contextNode, string name = null, params (Value, Block)[] incoming)
예제 #37
0
파일: ObjExpAST.cs 프로젝트: chenzuo/blue
    // Semantic resolution
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {   
        // Only resolve once.     
        if (m_symbol != null)
            return this;
            
        // First, resolve our parameters (because of overloading)
        // We need to know the URT types for our parameters
        // in order to resolve between overloaded operators
        
        Type [] alParamTypes = new Type[m_arParams.Length];
        
        
        for(int i = 0; i < m_arParams.Length; i++)        
        {
            Exp e = m_arParams[i];
            ResolveExpAsRight(ref e, s);
            Debug.Assert(e == m_arParams[i]);
            
            Type tParam = e.CLRType;
            
            //if ((tParam !=null) && tParam.IsByRef)
            //    tParam = tParam.GetElementType();
            
            alParamTypes[i] = tParam;
            //Debug.Assert(alParamTypes[i] != null);
            
        }   
        
        TypeEntry tCur = s.GetCurrentClass();    
        TypeEntry tLeft = null; // Type to lookup in   
        
        // Is this a 'base' access?
        // Convert to the real type and set a non-virtual flag
        if (m_objExp is SimpleObjExp)
        {
            SimpleObjExp e = m_objExp as SimpleObjExp;
            if (e.Name.Text == "base")
            {
                // Set the scope that we lookup in.
                tLeft = tCur.Super;
                
                // Still need to resolve the expression.
                m_objExp = new SimpleObjExp("this");               
                                               
                m_fIsNotPolymorphic = true;
            }
        }
        
#if true
        // See if we have a delegate here
        Exp eDelegate = null;
        if (m_objExp == null)
        {
            Exp e = new SimpleObjExp(m_idName);
            Exp.ResolveExpAsRight(ref e, s);
            if (!(e is SimpleObjExp))                
                eDelegate = e;
        } else {
            // If it's an interface, then we know we can't have a delegate field on it, 
            // so short-circuit now. 
            Exp.ResolveExpAsRight(ref m_objExp, s);
            if (!m_objExp.CLRType.IsInterface)
            {                
                Exp e = new DotObjExp(m_objExp, m_idName);
                Exp.ResolveExpAsRight(ref e, s);
                if (!(e is DotObjExp))                
                    eDelegate = e;        
            }
        }

        if (eDelegate != null)
        {
            if (!DelegateDecl.IsDelegate(eDelegate.CLRType))
            {
                //Debug.Assert(false, "@todo - " + m_strName + " is not a delegate or function"); // @todo - legit
                // Just fall through for now, method resolution will decide if this is a valid function
            } else 
            {            
                Exp e = new MethodCallExp(
                    eDelegate, 
                    new Identifier("Invoke"), 
                    this.m_arParams
                );
                
                Exp.ResolveExpAsRight(ref e, s);
                return e;        
            }
        }        
#endif    
        // No delegate, carry on with a normal function call
                        
        // If there's no objexp, then the function is a method
        // of the current class. 
        // make it either a 'this' or a static call
        if (m_objExp == null)
        {   
            // Lookup
            bool fIsVarArgDummy;
            MethodExpEntry sym = tCur.LookupMethod(s, m_idName, alParamTypes, out fIsVarArgDummy);
            
            if (sym.IsStatic)
            {                
                m_objExp = new TypeExp(tCur);
            } else {
                m_objExp = new SimpleObjExp("this");
            }
        }
        
        // Need to Lookup m_strName in m_objExp's scope (inherited scope)
        Exp.ResolveExpAsRight(ref m_objExp, s);
                    
                
        // Get type of of left side object
        // This call can either be a field on a variable
        // or a static method on a class
        
        bool fIsStaticMember = false;
        
        // If we don't yet know what TypeEntry this methodcall is on, then figure
        // it out based off the expression
        if (tLeft == null)
        {
            if (m_objExp is TypeExp)
            {
                fIsStaticMember = true;
                tLeft = ((TypeExp) m_objExp).Symbol;
            } else {
                fIsStaticMember = false;
                tLeft = s.ResolveCLRTypeToBlueType(m_objExp.CLRType);
            }
        }
        
        // Here's the big lookup. This will jump through all sorts of hoops to match
        // parameters, search base classes, do implied conversions, varargs, 
        // deal with abstract, etc.
        bool fIsVarArg;
        m_symbol = tLeft.LookupMethod(s, m_idName, alParamTypes, out fIsVarArg);
        Debug.Assert(m_symbol != null);
        
        if (m_fIsNotPolymorphic)
        {
            // of the form 'base.X(....)'
            if (m_symbol.IsStatic)
                ThrowError(SymbolError.BaseAccessCantBeStatic(this.Location, m_symbol)); // @todo - PrintError?
        } else {
            // normal method call
            /*
            if (fIsStaticMember && !m_symbol.IsStatic)
                ThrowError(SymbolError.ExpectInstanceMember(this.Location)); // @todo - PrintError?
            else if (!fIsStaticMember && m_symbol.IsStatic)                
                ThrowError(SymbolError.ExpectStaticMember(this.Location)); // @todo - PrintError?
            */
            Debug.Assert(fIsStaticMember == m_symbol.IsStatic, "@todo - user error. Mismatch between static & instance members on line.");
        }
        
        
        // If we have a vararg, then transform it 
        if (fIsVarArg)
        {
        // Create the array
            int cDecl = m_symbol.ParamCount;
            int cCall = this.ParamExps.Length;
            
            ArrayTypeSig tSig = new ArrayTypeSig(m_symbol.ParamCLRType(cDecl - 1), s);
            
            Node [] list = new Node[cCall - cDecl + 1];
            for(int i = 0; i < list.Length; i++)
            {
                list[i] = this.ParamExps[i + cDecl - 1];
            }
            
            Exp eArray = new NewArrayObjExp(
                tSig,
                new ArrayInitializer(
                    list
                )
            );
            
            Exp.ResolveExpAsRight(ref eArray, s);
            
        // Change the parameters to use the array    
            ArgExp [] arParams = new ArgExp[cDecl];
            for(int i = 0; i < cDecl - 1; i++)
                arParams[i] = m_arParams[i];
            arParams[cDecl - 1] = new ArgExp(EArgFlow.cIn, eArray);
            
            m_arParams = arParams;                            
        } // end vararg transformation
                
        this.CalcCLRType(s);
   
        return this;
    }