Пример #1
0
        //------------------------------------------------------------
        // CParser.ParseCollectionInitializer
        //
        /// <summary></summary>
        /// <param name="newNode"></param>
        //------------------------------------------------------------
        internal void ParseCollectionInitializer(NEWNODE newNode)
        {
            DebugUtil.Assert(CurrentTokenID() == TOKENID.OPENCURLY);
            NextToken();

            UNOPNODE initNode = AllocNode(NODEKIND.COLLECTIONINIT, newNode).AsCOLLECTIONINIT;

            CListMaker list  = new CListMaker(this);
            int        comma = -1;

            while (CurrentTokenID() != TOKENID.CLOSECURLY)
            {
                BASENODE nd = ParseVariableInitializer(initNode, false, -1);
                if (nd.Kind == NODEKIND.BINOP && nd.Operator == OPERATOR.ASSIGN)
                {
                    Error(CSCERRID.ERR_InvalidInitializerDeclarator);
                }
                else
                {
                    list.Add(nd, comma);
                }

                if (CurrentTokenID() != TOKENID.COMMA)
                {
                    break;
                }
                comma = CurrentTokenIndex();
                NextToken();
            }
            Eat(TOKENID.CLOSECURLY);

            initNode.Operand = list.GetList(initNode);
            if (initNode.Operand == null)
            {
                newNode.InitialNode = null;
                return;
            }

            newNode.InitialNode = initNode;
            newNode.Flags      |= NODEFLAGS.NEW_HAS_COLLECTION_INITIALIZER;

            if (newNode.ParentNode != null &&
                newNode.ParentNode.Kind == NODEKIND.VARDECL)
            {
                VARDECLNODE vdNode = newNode.ParentNode as VARDECLNODE;
                if (vdNode != null)
                {
                    newNode.Flags   |= NODEFLAGS.NEW_IN_VARDECL;
                    vdNode.NewFlags |= NODEFLAGS.NEW_HAS_COLLECTION_INITIALIZER;
                }
            }
            else if (newNode.ParentNode != null &&
                     newNode.ParentNode.Kind == NODEKIND.BINOP &&
                     newNode.Operator == OPERATOR.ASSIGN)
            {
                VARDECLNODE vdNode = newNode.ParentNode.ParentNode as VARDECLNODE;
                if (vdNode != null)
                {
                    newNode.Flags   |= NODEFLAGS.NEW_IN_VARDECL;
                    vdNode.NewFlags |= NODEFLAGS.NEW_HAS_COLLECTION_INITIALIZER;
                }
            }

            BASENODE node = newNode.ParentNode;

            while (node != null && !node.IsStatement)
            {
                node = node.ParentNode;
            }
            if (node != null)
            {
                (node as STATEMENTNODE).NewFlags |= NODEFLAGS.NEW_HAS_COLLECTION_INITIALIZER;
            }
        }
Пример #2
0
        //------------------------------------------------------------
        // FUNCBREC.BindObjectInitializer
        //
        /// <summary></summary>
        /// <param name="newNode"></param>
        /// <param name="typeSym"></param>
        /// <param name="locVarSym"></param>
        /// <param name="objectExpr"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal EXPR BindObjectInitializer(
            NEWNODE newNode,
            TYPESYM typeSym,
            LOCVARSYM locVarSym,
            EXPR objectExpr,
            StatementListBuilder builder)
        {
            DebugUtil.Assert(newNode != null && typeSym != null && builder != null);
            DebugUtil.Assert(
                (locVarSym != null && objectExpr == null) ||
                (locVarSym == null && objectExpr != null));

            BindFlagsEnum bindFlags   = BindFlagsEnum.RValueRequired;
            string        localFormat = "<{0}><{1}>__local";

            //--------------------------------------------------------
            // Bind the local variable.
            //--------------------------------------------------------
            if (locVarSym == null)
            {
                string typeName = typeSym.IsAGGTYPESYM ?
                                  (typeSym as AGGTYPESYM).GetAggregate().Name :
                                  typeSym.Name;
                string locName = String.Format(localFormat, typeName, (this.localCount)++);

                locVarSym = Compiler.LocalSymbolManager.CreateLocalSym(
                    SYMKIND.LOCVARSYM,
                    locName,
                    this.currentScopeSym) as LOCVARSYM;
                locVarSym.TypeSym             = typeSym;
                locVarSym.LocSlotInfo.HasInit = true;
                locVarSym.DeclTreeNode        = newNode;

                StoreInCache(newNode, locName, locVarSym, null, true);
            }

            EXPR locVarExpr = BindToLocal(
                newNode,
                locVarSym,
                bindFlags | BindFlagsEnum.MemberSet);

            //--------------------------------------------------------
            // If objectExpr is not null, assign it to the local variable.
            //--------------------------------------------------------
            if (objectExpr != null)
            {
                EXPR assignLocExpr = BindAssignment(
                    newNode,
                    locVarExpr,
                    objectExpr,
                    false);

                builder.Add(SetNodeStmt(newNode, MakeStmt(newNode, assignLocExpr, 0)));
            }

            //--------------------------------------------------------
            // Assign each value.
            //--------------------------------------------------------
            DECLSTMTNODE decNode = newNode.InitialNode as DECLSTMTNODE;

            DebugUtil.Assert(decNode != null);
            BASENODE node = decNode.VariablesNode;

            while (node != null)
            {
                VARDECLNODE varDecl;
                if (node.Kind == NODEKIND.LIST)
                {
                    varDecl = node.AsLIST.Operand1 as VARDECLNODE;
                    node    = node.AsLIST.Operand2;
                }
                else
                {
                    varDecl = node as VARDECLNODE;
                    node    = null;
                }

                BINOPNODE assignNode = varDecl.ArgumentsNode as BINOPNODE;
                if (assignNode == null ||
                    assignNode.Operator != OPERATOR.ASSIGN ||
                    assignNode.Operand1 == null ||
                    assignNode.Operand1.Kind != NODEKIND.NAME ||
                    assignNode.Operand2 == null)
                {
                    continue;
                }

                //----------------------------------------------------
                // LHS
                //----------------------------------------------------
                NAMENODE nameNode = assignNode.Operand1 as NAMENODE;
                DebugUtil.Assert(nameNode != null);

                bindFlags = BindFlagsEnum.MemberSet;
                MemberLookup mem = new MemberLookup();

                EXPR leftExpr = null;
                if (mem.Lookup(
                        Compiler,
                        typeSym,
                        locVarExpr,
                        this.parentDeclSym,
                        nameNode.Name,
                        0,
                        MemLookFlagsEnum.UserCallable))
                {
                    SymWithType swt = mem.FirstSymWithType;
                    DebugUtil.Assert(swt != null && swt.IsNotNull);

                    switch (swt.Sym.Kind)
                    {
                    case SYMKIND.MEMBVARSYM:
                        leftExpr = BindToField(
                            assignNode,
                            locVarExpr,
                            FieldWithType.Convert(swt),
                            bindFlags);
                        break;

                    case SYMKIND.PROPSYM:
                        leftExpr = BindToProperty(
                            assignNode,
                            locVarExpr,
                            PropWithType.Convert(swt),
                            bindFlags,
                            null,
                            null);
                        break;

                    default:
                        leftExpr = NewError(nameNode, null);
                        break;
                    }
                }
                else
                {
                    mem.ReportErrors(nameNode);
                    leftExpr = NewError(nameNode, null);
                }

                //----------------------------------------------------
                // Collection initializer
                //----------------------------------------------------
                if (assignNode.Operand2.Kind == NODEKIND.ARRAYINIT)
                {
                    if (!leftExpr.TypeSym.IsARRAYSYM)
                    {
                        BindCollectionInitializer(
                            newNode,
                            (assignNode.Operand2 as UNOPNODE).Operand,
                            leftExpr.TypeSym, //typeSym,
                            null,             //locVarSym,
                            leftExpr,
                            null,
                            builder);
                        continue;
                    }
                }

                //----------------------------------------------------
                // RHS
                //----------------------------------------------------
                EXPR rightExpr = BindExpr(
                    assignNode.Operand2,
                    BindFlagsEnum.RValueRequired);

                //----------------------------------------------------
                // Assign
                //----------------------------------------------------
                EXPR assignExpr = BindAssignment(
                    assignNode,
                    leftExpr,
                    rightExpr,
                    false);

                builder.Add(SetNodeStmt(decNode, MakeStmt(decNode, assignExpr, 0)));
            }

            return(locVarExpr);
        }
Пример #3
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubHasValue
        //
        /// <summary>
        /// <para>Create an expr for exprSrc.HasValue where exprSrc->type is a NUBSYM.</para>
        /// <para>If fCheckTrue is false, invert the result.</para>
        /// <para>(In sscli, checkTrue has the default value true.)</para>
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="srcExpr"></param>
        /// <param name="checkTrue"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private EXPR BindNubHasValue(
            BASENODE treeNode,
            EXPR srcExpr,
            bool checkTrue) // = true
        {
            DebugUtil.Assert(srcExpr != null && srcExpr.TypeSym.IsNUBSYM);

            TYPESYM boolTypeSym = GetRequiredPredefinedType(PREDEFTYPE.BOOL);

            // When srcExpr is a null, the result is false
            if (srcExpr.GetConst() != null)
            {
                return(AddSideEffects(
                           treeNode,
                           NewExprConstant(treeNode, boolTypeSym, new ConstValInit(!checkTrue)),
                           srcExpr,
                           true,
                           true));
            }

            // For new T?(x), the answer is true.
            if (IsNubCtor(srcExpr))
            {
                return(AddSideEffects(
                           treeNode,
                           NewExprConstant(treeNode, boolTypeSym, new ConstValInit(checkTrue)),
                           StripNubCtor(srcExpr),
                           true,
                           true));
            }

            AGGTYPESYM aggTypeSym = (srcExpr.TypeSym as NUBSYM).GetAggTypeSym();

            if (aggTypeSym == null)
            {
                return(NewError(treeNode, boolTypeSym));
            }
            Compiler.EnsureState(aggTypeSym, AggStateEnum.Prepared);

            PROPSYM propSym = EnsureNubHasValue(treeNode);

            if (propSym == null)
            {
                return(NewError(treeNode, boolTypeSym));
            }

            CheckFieldUse(srcExpr, true);

            EXPRPROP resExpr = NewExpr(treeNode, EXPRKIND.PROP, boolTypeSym) as EXPRPROP;

            resExpr.SlotPropWithType.Set(propSym, aggTypeSym);
            resExpr.GetMethodWithType.Set(propSym.GetMethodSym, aggTypeSym);
            resExpr.ArgumentsExpr = null;
            resExpr.ObjectExpr    = srcExpr;

            if (checkTrue)
            {
                return(resExpr);
            }

            return(NewExprBinop(treeNode, EXPRKIND.LOGNOT, resExpr.TypeSym, resExpr, null));
        }
Пример #4
0
        //------------------------------------------------------------
        // CAsmLink::SetPEKind (sscli)
        //------------------------------------------------------------
        //virtual internal HRESULT SetPEKind(
        //    mdAssembly AssemblyID,
        //    mdToken FileToken,
        //    DWORD dwPEKind,
        //    DWORD dwMachine)
        //{
        //    ASSERT(m_bInited && !m_bAssemblyEmitted && !m_bPreClosed);
        //    ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM);
        //    ASSERT((FileToken == AssemblyID) ||
        //        (TypeFromToken(FileToken) == mdtFile && RidFromToken(FileToken) < m_pAssem->CountFiles()) ||
        //        (TypeFromToken(FileToken) == mdtAssemblyRef && RidFromToken(FileToken) < m_pImports->CountFiles()) ||
        //        (TypeFromToken(FileToken) == mdtModule && RidFromToken(FileToken) < m_pModules->CountFiles()));
        //
        //    HRESULT hr = E_INVALIDARG;
        //    CFile* file = NULL;
        //
        //    if (TypeFromToken(FileToken) == mdtAssemblyRef) {
        //        hr = m_pImports->GetFile( FileToken, &file);
        //    } else if (TypeFromToken(FileToken) == mdtModule) {
        //        hr = m_pModules->GetFile( FileToken, &file);
        //    } else if (FileToken == AssemblyID) {
        //        file = m_pAssem;
        //        hr = S_OK;
        //    } else if (TypeFromToken(FileToken) == mdtFile) {
        //        if (AssemblyID == AssemblyIsUBM)
        //            m_pAssem->SetPEKind( dwPEKind, dwMachine);
        //        hr = m_pAssem->GetFile( FileToken, &file);
        //    }
        //
        //    if (SUCCEEDED(hr)) {
        //        file->SetPEKind( dwPEKind, dwMachine);
        //
        //        DWORD cnt = m_pImports->CountFiles();
        //        for (DWORD i = 0; i < cnt; i++) {
        //            CFile * ref = NULL;
        //            if (FAILED(hr = m_pImports->GetFile( i, &ref)) ||
        //                S_OK != (hr = m_pAssem->ComparePEKind( ref, false)))
        //                return hr;
        //        }
        //    }
        //
        //    return hr;
        //}

        //------------------------------------------------------------
        // CAsmLink.ImportTypes
        //------------------------------------------------------------
        // virtual internal HRESULT  ImportTypes(mdAssembly AssemblyID, mdToken FileToken, DWORD dwScope, HALINKENUM* phEnum,
        //     IMetaDataImport **ppImportScope, DWORD* pdwCountOfTypes);
        // virtual internal HRESULT  ImportTypes2(mdAssembly AssemblyID, mdToken FileToken, DWORD dwScope, HALINKENUM* phEnum,
        //     IMetaDataImport2 **ppImportScope, DWORD* pdwCountOfTypes);
        // virtual internal HRESULT  EnumCustomAttributes(HALINKENUM hEnum, mdToken tkType, mdCustomAttribute rCustomValues[],
        //     ULONG cMax, ULONG *pcCustomValues);
        // virtual internal HRESULT  EnumImportTypes(HALINKENUM hEnum, DWORD dwMax, mdTypeDef aTypeDefs[], DWORD* pdwCount);
        // virtual internal HRESULT  CloseEnum(HALINKENUM hEnum);

        // Exporting

        // virtual internal HRESULT  ExportType(mdAssembly AssemblyID, mdToken FileToken, mdTypeDef TypeToken,
        //     LPCWSTR pszTypename, DWORD dwFlags, mdExportedType* pType);
        // virtual internal HRESULT  ExportNestedType(mdAssembly AssemblyID, mdToken FileToken, mdTypeDef TypeToken,
        //     mdExportedType ParentType, LPCWSTR pszTypename, DWORD dwFlags, mdExportedType* pType);

        //------------------------------------------------------------
        // CAsmLink.EmitInternalExportedTypes
        //------------------------------------------------------------
        virtual internal bool EmitInternalExportedTypes()
        {
            DebugUtil.Assert(this.inited && !this.assemblyEmitted && !this.preClosed);
            return(this.assemblyBuilderEx.EmitInternalTypes());
        }
Пример #5
0
        //------------------------------------------------------------
        // ERRLOC.SetEnd
        //
        /// <summary>
        /// Recursively searches parse-tree for correct right-most node
        /// </summary>
        /// <param name="node"></param>
        //------------------------------------------------------------
        internal void SetEnd(BASENODE node)
        {
            if (startPos.IsUninitialized)
            {
                return;
            }

            LEXDATA ld = sourceData.LexData;

            if (node == null || node.TokenIndex == -1 || ld == null)
            {
                return;
            }

            SetEndInternal(ld, node);

            switch (node.Kind)
            {
            case NODEKIND.ACCESSOR:
                // Get and Set always are the token before the '{'
                SetEndInternal(ld, (node as ACCESSORNODE).OpenCurlyIndex, -1);
                return;

            case NODEKIND.ARROW:        // BINOPNODE
                if (node.AsARROW.Operand2 != null)
                {
                    SetEnd(node.AsARROW.Operand2);
                }
                return;

            case NODEKIND.ATTR:                   // ATTRNODE
                if ((node as ATTRNODE).NameNode != null)
                {
                    SetEnd((node as ATTRNODE).NameNode);
                }
                return;

            case NODEKIND.ATTRDECL:
                if ((node as ATTRDECLNODE).NameNode != null)
                {
                    SetEnd((node as ATTRDECLNODE).NameNode);
                }
                return;

            case NODEKIND.ANONBLOCK:
                if ((node as ANONBLOCKNODE).CloseParenIndex != -1)
                {
                    // Try to grab the parameters
                    SetEndInternal(ld, (node as ANONBLOCKNODE).CloseParenIndex, 0);
                    // Try to grab the open-curly
                    SetEndInternal(ld, (node as ANONBLOCKNODE).CloseParenIndex, 1);
                }

                // And possibly the entire block
                SetEndInternal(
                    ld,
                    ((node as ANONBLOCKNODE).BodyNode as BLOCKNODE).CloseCurlyIndex,
                    0);
                return;

            case NODEKIND.LAMBDAEXPR:
                if ((node as LAMBDAEXPRNODE).BodyNode.Kind == NODEKIND.BLOCK)
                {
                    SetEndInternal(
                        ld,
                        ((node as LAMBDAEXPRNODE).BodyNode as BLOCKNODE).CloseCurlyIndex,
                        0);
                }
                else
                {
                    SetEnd((node as LAMBDAEXPRNODE).BodyNode);
                }
                return;

            case NODEKIND.CALL:     // CALL
            case NODEKIND.DEREF:
                SetEndInternal(ld, node.AsANYCALL.CloseParenIndex, 0);
                return;

            case NODEKIND.BINOP:        // BINOPNODE
                if ((node as BINOPNODE).Operand2 != null)
                {
                    SetEnd((node as BINOPNODE).Operand2);
                }
                return;

            case NODEKIND.LIST:
                SetEnd(node.AsANYBINOP.Operand2);
                return;

            case NODEKIND.CLASS:        //CLASSNODE
            case NODEKIND.INTERFACE:
            case NODEKIND.STRUCT:
                if (node.AsAGGREGATE.NameNode != null)
                {
                    SetEnd(node.AsAGGREGATE.NameNode);
                }
                return;

            case NODEKIND.CTOR:
            case NODEKIND.DTOR:
            {
                int i;
                for (i = node.TokenIndex;
                     i < ld.TokenCount && ld.TokenAt(i).TokenID != TOKENID.IDENTIFIER;
                     i++)
                {
                    ;
                }
                SetEndInternal(ld, i, 0);
                return;
            }

            case NODEKIND.DELEGATE:
                if ((node as DELEGATENODE).NameNode != null)
                {
                    SetEnd((node as DELEGATENODE).NameNode);
                }
                return;

            case NODEKIND.DOT:      // BINOPNODE
                if (node.AsDOT.Operand2 != null)
                {
                    SetEnd(node.AsDOT.Operand2);
                }
                return;

            case NODEKIND.ENUM:
                if ((node as ENUMNODE).NameNode != null)
                {
                    SetEnd((node as ENUMNODE).NameNode);
                }
                return;

            case NODEKIND.GENERICNAME:
                SetEndInternal(ld, (node as GENERICNAMENODE).CloseAngleIndex, 0);
                return;

            case NODEKIND.INDEXER:
            {
                int i;
                for (i = node.TokenIndex; i < ld.TokenCount; i++)
                {
                    SetEndInternal(ld, i, 0);
                    if (ld.TokenAt(i).TokenID == TOKENID.THIS)
                    {
                        break;
                    }
                }

                return;
            }

            case NODEKIND.METHOD:       // METHODNODE
                // use the name to keep the the same as fields
                if ((node as METHODNODE).NameNode != null)
                {
                    SetEnd((node as METHODNODE).NameNode);
                }
                return;

            case NODEKIND.NAMESPACE:
                // use the name to keep the the same as fields
                if ((node as NAMESPACENODE).NameNode != null)
                {
                    SetEnd((node as NAMESPACENODE).NameNode);
                }
                return;

            case NODEKIND.OPERATOR:
            {
                int i;
                for (i = node.TokenIndex;
                     i < ld.TokenCount - 1 && ld.TokenAt(i).TokenID != TOKENID.OPERATOR;
                     i++)
                {
                    SetEndInternal(ld, i, 0);
                }

                SetEndInternal(ld, i, 0);
                if ((node as OPERATORMETHODNODE).Operator == OPERATOR.IMPLICIT ||
                    (node as OPERATORMETHODNODE).Operator == OPERATOR.EXPLICIT)
                {
                    // for conversion operators the type is the end of the name
                    // (or the token before the open paren)
                    SetEndInternal(ld, (node as OPERATORMETHODNODE).OpenParenIndex, -1);
                }
                else
                {
                    // For non-conversion operators the token after 'operator'
                    // which is the end of the 'name'
                    SetEndInternal(ld, i, 1);
                }

                return;
            }

            case NODEKIND.NEW:
                // The type is the most important
                SetEnd((node as NEWNODE).TypeNode);
                // But try to get the arguments/array indexes
                SetEndInternal(ld, (node as NEWNODE).CloseParenIndex, 0);
                return;

            case NODEKIND.PROPERTY:
                if (node.AsANYPROPERTY.NameNode != null)
                {
                    SetEnd(node.AsANYPROPERTY.NameNode);
                }
                return;

            case NODEKIND.PREDEFINEDTYPE:
            case NODEKIND.POINTERTYPE:
            case NODEKIND.NULLABLETYPE:
                return;

            case NODEKIND.NAMEDTYPE:
                SetEnd((node as NAMEDTYPENODE).NameNode);
                return;

            case NODEKIND.ARRAYTYPE:
                // For array types, the token index is the open '['.  Add the number of
                // dimensions and you land on the ']' (1==[], 2==[,], 3==[,,], etc).
                if ((node as ARRAYTYPENODE).Dimensions == -1)
                {
                    SetEndInternal(ld, node.TokenIndex, 2);     // unknown rank is [?]
                }
                else
                {
                    SetEndInternal(ld, node.TokenIndex, (node as ARRAYTYPENODE).Dimensions);
                }
                return;

            case NODEKIND.UNOP:
                switch (node.Operator)
                {
                case OPERATOR.PAREN:
                case OPERATOR.PREINC:
                case OPERATOR.PREDEC:
                    SetEnd((node as UNOPNODE).Operand);
                    break;

                default:
                    break;
                }
                return;

            case NODEKIND.QUERYEXPR:
                SetEnd((node as QUERYEXPRNODE).QueryBodyNode);
                break;

            case NODEKIND.FROMCLAUSE:
            case NODEKIND.FROMCLAUSE2:
                SetEnd((node as FROMCLAUSENODE).ExpressionNode);
                break;

            case NODEKIND.LETCLAUSE:
                SetEnd((node as LETCLAUSENODE).ExpressionNode);
                break;

            case NODEKIND.WHERECLAUSE:
                SetEnd((node as WHERECLAUSENODE).LambdaExpressionNode);
                break;

            case NODEKIND.JOINCLAUSE:
                JOINCLAUSENODE joinNode = node as JOINCLAUSENODE;
                DebugUtil.Assert(joinNode != null);
                if (joinNode.IntoNameNode != null)
                {
                    SetEnd(joinNode.IntoNameNode);
                }
                else
                {
                    if (joinNode.IntoNameNode != null)
                    {
                        SetEnd(joinNode.IntoNameNode);
                    }
                    else
                    {
                        SetEnd(joinNode.EqualRightLambdaExpressionNode);
                    }
                }
                break;

            case NODEKIND.ORDERBYCLAUSE:
                ORDERBYCLAUSENODE obNode = node as ORDERBYCLAUSENODE;
                DebugUtil.Assert(obNode != null);
                if (obNode.LastOrdering != null)
                {
                    SetEnd(obNode.LastOrdering.LambdaExpressionNode);
                }
                else
                {
                    return;
                }
                break;

            case NODEKIND.SELECTCLAUSE:
                SetEnd((node as SELECTCLAUSENODE).LambdaExpressionNode);
                break;

            case NODEKIND.GROUPCLAUSE:
                SetEnd((node as GROUPCLAUSENODE).ByExpressionNode);
                break;

            case NODEKIND.QUERYCONTINUATION:
                SetEnd((node as QUERYCONTINUATIONNODE).QueryBodyNode);
                break;

            default:
                break;
            }
        }
Пример #6
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubConversion
        //
        // Called by bindImplicitConversion when the destination type is Nullable&lt;T&gt;. The following
        // conversions are handled by this method:
        //
        // * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit
        // unboxing conversion S =&gt; T?
        // * System.Enum =&gt; T? there is an unboxing conversion if T is an enum type
        // * null =&gt; T? implemented as default(T?)
        //
        // * Implicit T?* =&gt; T?+ implemented by either wrapping or calling GetValueOrDefault the
        // appropriate number of times.
        // * If imp/exp S =&gt; T then imp/exp S =&gt; T?+ implemented by converting to T then wrapping the
        // appropriate number of times.
        // * If imp/exp S =&gt; T then imp/exp S?+ =&gt; T?+ implemented by calling GetValueOrDefault (m-1) times
        // then calling HasValue, producing a null if it returns false, otherwise calling Value,
        // converting to T then wrapping the appropriate number of times.
        //
        // The 3 rules above can be summarized with the following recursive rules:
        //
        // * If imp/exp S =&gt; T? then imp/exp S? =&gt; T? implemented as
        // qs.HasValue ? (T?)(qs.Value) : default(T?)
        // * If imp/exp S =&gt; T then imp/exp S =&gt; T? implemented as new T?((T)s)
        //
        // This method also handles calling bindUserDefinedConverion. This method does NOT handle
        // the following conversions:
        //
        // * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by bindImplicitConversion.)
        // * If imp/exp S =&gt; T then explicit S?+ =&gt; T implemented by calling Value the appropriate number
        // of times. (Handled by bindExplicitConversion.)
        //
        // The recursive equivalent is:
        //
        // * If imp/exp S =&gt; T and T is not nullable then explicit S? =&gt; T implemented as qs.Value
        //
        // Some nullable conversion are NOT standard conversions. In particular, if S =&gt; T is implicit
        // then S? =&gt; T is not standard. Similarly if S =&gt; T is not implicit then S =&gt; T? is not standard.
        //
        /// <summary></summary>
        /// <param name="treeNode"></param>
        /// <param name="srcExpr"></param>
        /// <param name="srcTypeSym"></param>
        /// <param name="dstNubSym"></param>
        /// <param name="dstExpr"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private bool BindNubConversion(
            BASENODE treeNode,
            EXPR srcExpr,
            TYPESYM srcTypeSym,
            NUBSYM dstNubSym,
            ref EXPR dstExpr,
            ConvertTypeEnum flags)
        {
            // This code assumes that STANDARD and ISEXPLICIT are never both set.
            // bindUserDefinedConversion should ensure this!
            DebugUtil.Assert((~flags & (ConvertTypeEnum.STANDARD | ConvertTypeEnum.ISEXPLICIT)) != 0);

            DebugUtil.Assert(srcExpr == null || srcExpr.TypeSym == srcTypeSym);
            DebugUtil.Assert(dstExpr == null || srcExpr != null);

            DebugUtil.Assert(srcTypeSym != dstNubSym);
            // bindImplicitConversion should have taken care of this already.

            AGGTYPESYM dstAggTypeSym = dstNubSym.GetAggTypeSym();

            if (dstAggTypeSym == null)
            {
                return(false);
            }

            // Check for the unboxing conversion. This takes precedence over the wrapping conversions.
            if (Compiler.IsBaseType(dstNubSym.BaseTypeSym, srcTypeSym) && !FWrappingConv(srcTypeSym, dstNubSym))
            {
                // These should be different! Fix the caller if srcTypeSym is an AGGTYPESYM of Nullable.
                DebugUtil.Assert(dstAggTypeSym != srcTypeSym);

                // srcTypeSym is a base type of the destination nullable type so there is an explicit
                // unboxing conversion.
                if ((flags & ConvertTypeEnum.ISEXPLICIT) == 0)
                {
                    return(false);
                }
                return(BindSimpleCast(treeNode, srcExpr, dstNubSym, ref dstExpr, EXPRFLAG.UNBOX));
            }

            int     dstNubStripCount;
            int     srcNubStripCount;
            TYPESYM dstBaseTypeSym = dstNubSym.StripNubs(out dstNubStripCount);
            TYPESYM srcBaseTypeSym = srcTypeSym.StripNubs(out srcNubStripCount);

            bindNubConversion_Convert fnConvert;
            EXPR expr = null;   // temp

            if ((flags & ConvertTypeEnum.ISEXPLICIT) != 0)
            {
                fnConvert = new bindNubConversion_Convert(BindExplicitConversion);
            }
            else
            {
                fnConvert = new bindNubConversion_Convert(BindImplicitConversion);
            }

            //bool (FUNCBREC::*pfn)(BASENODE *, EXPR *, TYPESYM *, TYPESYM *, EXPR **, uint) =
            //    (flags & ISEXPLICIT) ? &FUNCBREC::bindExplicitConversion : &FUNCBREC::bindImplicitConversion;

            if (srcNubStripCount == 0)
            {
                DebugUtil.Assert(srcTypeSym == srcBaseTypeSym);

                // The null type can be implicitly converted to T? as the default value.
                if (srcTypeSym.IsNULLSYM)
                {
                    dstExpr = AddSideEffects(treeNode, NewExprZero(treeNode, dstNubSym), srcExpr, true, true);
                    return(true);
                }

                EXPR tempExpr = srcExpr;

                // If there is an implicit/explicit S => T then there is an implicit/explicit S => T?
                if (srcTypeSym == dstBaseTypeSym ||
                    fnConvert(
                        treeNode,
                        srcExpr,
                        srcTypeSym,
                        dstBaseTypeSym,
                        ref tempExpr,
                        flags | ConvertTypeEnum.NOUDC))
                {
                    // srcTypeSym is not nullable so just wrap the required number of times.
                    for (int i = 0; i < dstNubStripCount; i++)
                    {
                        tempExpr = BindNubNew(treeNode, tempExpr);
                    }
                    DebugUtil.Assert(tempExpr.TypeSym == dstNubSym);
                    dstExpr = tempExpr;
                    return(true);
                }

                // No builtin conversion. Maybe there is a user defined conversion....
                return(
                    (flags & ConvertTypeEnum.NOUDC) == 0 &&
                    BindUserDefinedConversion(
                        treeNode,
                        srcExpr,
                        srcTypeSym,
                        dstNubSym,
                        ref dstExpr,
                        (flags & ConvertTypeEnum.ISEXPLICIT) == 0));
            }

            // Both are Nullable so there is only a conversion if there is a conversion between the base types.
            // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+.
            if (srcBaseTypeSym != dstBaseTypeSym &&
                !fnConvert(treeNode, null, srcBaseTypeSym, dstBaseTypeSym, ref expr, flags | ConvertTypeEnum.NOUDC))
            {
                // No builtin conversion. Maybe there is a user defined conversion....
                return(
                    (flags & ConvertTypeEnum.NOUDC) == 0 &&
                    BindUserDefinedConversion(
                        treeNode,
                        srcExpr,
                        srcTypeSym,
                        dstNubSym,
                        ref dstExpr,
                        (flags & ConvertTypeEnum.ISEXPLICIT) == 0));
            }

            // We need to go all the way down to the base types, do the conversion, then come all the way back up.
            EXPR    valExpr;
            NubInfo nubInfo = new NubInfo();

            BindNubCondValBin(
                treeNode,
                srcExpr,
                null,
                ref nubInfo,
                LiftFlagsEnum.LiftBoth);
            valExpr = nubInfo.Val(0);

            DebugUtil.Assert(valExpr.TypeSym == srcBaseTypeSym);

            if (!fnConvert(
                    treeNode,
                    valExpr,
                    valExpr.TypeSym,
                    dstBaseTypeSym,
                    ref valExpr,
                    flags | ConvertTypeEnum.NOUDC))
            {
                DebugUtil.Assert(false, "bind(Im|Ex)plicitConversion failed unexpectedly");
                return(false);
            }

            for (int i = 0; i < dstNubStripCount; i++)
            {
                valExpr = BindNubNew(treeNode, valExpr);
            }
            DebugUtil.Assert(valExpr.TypeSym == dstNubSym);

            dstExpr = BindNubOpRes(treeNode, dstNubSym, dstNubSym, valExpr, ref nubInfo, false);

            return(true);
        }
Пример #7
0
 //------------------------------------------------------------
 // ConsoleOutput.WriteLine (3)
 //
 /// <summary></summary>
 /// <param name="fmt"></param>
 /// <param name="args"></param>
 //------------------------------------------------------------
 internal void WriteLine(string fmt, params Object[] args)
 {
     DebugUtil.Assert(this.consoleObject != null);
     this.consoleObject.WriteLine(this.FormatString(fmt, args));
 }
Пример #8
0
        //------------------------------------------------------------
        // FUNCBREC.HasIEnumerable (2)
        //
        /// <summary>
        /// Rewrite HasIEnumerable for collection initializer.
        /// Return the IEnumerable or IEnumerable&lt;T&gt; instance.
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="tree"></param>
        /// <param name="badType"></param>
        /// <param name="badMember"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private AGGTYPESYM HasIEnumerable(
            TYPESYM collectionTypeSym/*,
                                      * BASENODE treeNode,
                                      * TYPESYM badTypeSym,
                                      * PREDEFNAME badMemberName*/
            )
        {
            AGGTYPESYM ifaceCandidateAts = null;
            // First try the generic interfaces
            AGGSYM gEnumAggSym
                = Compiler.GetOptPredefAgg(PREDEFTYPE.G_IENUMERABLE, true);
            TypeArray  allIfacesTypeArray = null;
            AGGTYPESYM baseAts            = null;

            // If generics don't exist or the type isn't an AGGTYPESYM
            // then we can't check the interfaces (and base-class interfaces)
            // for IEnumerable<T> so immediately try the non-generic IEnumerable
            if (gEnumAggSym == null)
            {
                goto NO_GENERIC;
            }

            if (collectionTypeSym.IsAGGTYPESYM)
            {
                if (collectionTypeSym.GetAggregate() == gEnumAggSym ||
                    collectionTypeSym.IsPredefType(PREDEFTYPE.IENUMERABLE))
                {
                    DebugUtil.Assert(false, "IEnumerable/ator types are bad!");
                    goto LERROR;
                }

                AGGTYPESYM tempAts = collectionTypeSym as AGGTYPESYM;
                allIfacesTypeArray = tempAts.GetIfacesAll();
                baseAts            = tempAts.GetBaseClass();
            }
            else if (collectionTypeSym.IsTYVARSYM)
            {
                // Note:
                // we'll search the interface list before the class constraint,
                // but it doesn't matter since we require a unique instantiation of IEnumerable<T>.

                // Note:
                // The pattern search will usually find the interface constraint
                // - but if the class constraint has a non-public or non-applicable
                // or non-method GetEnumerator,
                // the interfaces are hidden in which case we will find them here.

                TYVARSYM tempTvSym = collectionTypeSym as TYVARSYM;
                allIfacesTypeArray = tempTvSym.AllInterfaces;
                baseAts            = tempTvSym.BaseClassSym;
            }
            else
            {
                goto NO_GENERIC;
            }

            DebugUtil.Assert(allIfacesTypeArray != null);

            // If the type implements exactly one instantiation of
            // IEnumerable<T> then it's the one.
            //
            // If it implements none then try the non-generic interface.
            //
            // If it implements more than one, then it's an error.
            //
            // Search the direct and indirect interfaces via allIfacesTypeArray,
            // going up the base chain...
            // Work up the base chain
            for (; ;)
            {
                // Now work across all the interfaces
                for (int i = 0; i < allIfacesTypeArray.Count; ++i)
                {
                    AGGTYPESYM iface = allIfacesTypeArray[i] as AGGTYPESYM;
                    if (iface.GetAggregate() == gEnumAggSym)
                    {
                        if (ifaceCandidateAts == null)
                        {
                            // First implementation
                            ifaceCandidateAts = iface;
                        }
                        else if (iface != ifaceCandidateAts)
                        {
                            // If this really is a different instantiation report an error
                            Compiler.Error(
                                treeNode,
                                CSCERRID.ERR_MultipleIEnumOfT,
                                new ErrArgRef(collectionTypeSym),
                                new ErrArg(gEnumAggSym.GetThisType()));
                            return(null);
                        }
                    }
                }
                // Check the base class.
                if (baseAts == null)
                {
                    break;
                }
                allIfacesTypeArray = baseAts.GetIfacesAll();
                baseAts            = baseAts.GetBaseClass();
            }

            // Report the one and only generic interface
            if (ifaceCandidateAts != null)
            {
                DebugUtil.Assert(
                    CanConvert(collectionTypeSym, ifaceCandidateAts, ConvertTypeEnum.NOUDC));
                return(ifaceCandidateAts);
            }

NO_GENERIC:
            if (collectionTypeSym.IsPredefType(PREDEFTYPE.IENUMERABLE))
            {
                DebugUtil.VsFail("Why didn't IEnumerator match the pattern?");
                goto LERROR;
            }

            // No errors, no generic interfaces, try the non-generic interface
            ifaceCandidateAts = GetRequiredPredefinedType(PREDEFTYPE.IENUMERABLE);
            if (CanConvert(collectionTypeSym, ifaceCandidateAts, ConvertTypeEnum.NOUDC))
            {
                return(ifaceCandidateAts);
            }

LERROR:
            return(null);
        }
Пример #9
0
        //------------------------------------------------------------
        // CSConsoleArgs.ExpandResponseFiles
        //
        /// <summary>
        /// <para>(ConsoleArgs::ProcessResponseArgs in sscli.)</para>
        /// <para>Process Response files on the command line
        /// Returns true if it allocated a new argv array that must be freed later</para>
        /// <para>コマンドラインでレスポンスファイルが指定されていたら、
        /// その内容をオプションリストに追加する。
        /// (レスポンスファイルは @ファイル名 の形式で指定されている。)</para>
        /// </summary>
        //------------------------------------------------------------
        private void ExpandResponseFiles()
        {
            Dictionary <string, bool> processedResponseFiles
                = new Dictionary <string, bool>(new StringEqualityComparerIgnoreCase());
            List <string[]> listTemp     = null;
            string          fileName     = null;
            string          fullName     = null;
            string          fileContents = null;
            Exception       excp         = null;
            bool            foundResponseFile;
            int             loopCount    = 0;
            const int       maxLoopCount = 32;

            do
            {
                if (loopCount >= maxLoopCount)
                {
                    throw new Exception("Too many nested response file.");
                }

                listTemp          = new List <string[]>();
                foundResponseFile = false;
                foreach (string[] opt in this.OptionList)
                {
                    // オプションが null や空の場合は破棄する。
                    if (opt == null || opt.Length == 0)
                    {
                        continue;
                    }
                    // 1 文字目が @ でないものはそのままリストに追加する。
                    if (opt[1] != "@")
                    {
                        listTemp.Add(opt);
                        continue;
                    }

                    if (opt.Length <= 2 || String.IsNullOrEmpty(opt[2]))
                    {
                        this.Controller.ReportError(
                            CSCERRID.ERR_NoFileSpec,
                            ERRORKIND.ERROR,
                            opt[0]);
                        continue;
                    }

                    // Check for duplicates
                    // @ と引用符を外す。
                    fileName = opt[2];

                    IOUtil.RemoveQuotes(ref fileName);

                    if (String.IsNullOrEmpty(fileName))
                    {
                        this.Controller.ReportError(
                            CSCERRID.ERR_NoFileSpec,
                            ERRORKIND.ERROR,
                            opt[0]);
                        continue;
                    }

                    // ファイルのフルパスを求める。
                    fullName = this.GetFullFileName(fileName, false);
                    if (String.IsNullOrEmpty(fullName))
                    {
                        this.Controller.ReportError(
                            CSCERRID.ERR_NoFileSpec,
                            ERRORKIND.ERROR,
                            opt[0]);
                        continue;
                    }

                    // 得られたファイルがすでに処理されていないか調べる。
                    try
                    {
                        if (processedResponseFiles.ContainsKey(fullName))
                        {
                            continue;
                        }
                    }
                    catch (ArgumentException)
                    {
                        DebugUtil.Assert(false);
                        continue;
                    }

                    // ファイルの内容を読み込む。エラーの場合はメッセージを表示して次へ。
                    if (!IOUtil.ReadTextFile(fullName, null, out fileContents, out excp))
                    {
                        this.Controller.ReportError(ERRORKIND.ERROR, excp.Message);
                        continue;
                    }

                    // レスポンスファイル内で指定されているオプションを取得する。
                    TextToArgs(fileContents, listTemp);
                    foundResponseFile = true;

                    // 処理済みファイルのリストに追加する。
                    processedResponseFiles.Add(fullName, true);
                }
                this.OptionList = listTemp;
                ++loopCount;
            } while (foundResponseFile);
        }
Пример #10
0
 //------------------------------------------------------------
 // ConsoleOutput.WriteLine (1)
 //
 /// <summary>
 /// <para>Output an empty line.</para>
 /// <para>(PrintBlankLine in sscli)</para>
 /// </summary>
 //------------------------------------------------------------
 internal void WriteLine()
 {
     DebugUtil.Assert(this.consoleObject != null);
     this.consoleObject.WriteLine();
 }
Пример #11
0
        //------------------------------------------------------------
        // FUNCBREC.OperatorToExpressionType
        //
        /// <summary></summary>
        /// <param name="op"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal ExpressionType OperatorToExpressionType(OPERATOR op)
        {
            switch (op)
            {
            case OPERATOR.NONE:
                //return ExpressionType;
                break;

            case OPERATOR.ASSIGN:
                return(ExpressionType.Assign);

            case OPERATOR.ADDEQ:
                return(ExpressionType.AddAssign);

            case OPERATOR.SUBEQ:
                return(ExpressionType.SubtractAssign);

            case OPERATOR.MULEQ:
                return(ExpressionType.MultiplyAssign);

            case OPERATOR.DIVEQ:
                return(ExpressionType.DivideAssign);

            case OPERATOR.MODEQ:
                return(ExpressionType.ModuloAssign);

            case OPERATOR.ANDEQ:
                return(ExpressionType.AndAssign);

            case OPERATOR.XOREQ:
                return(ExpressionType.ExclusiveOrAssign);

            case OPERATOR.OREQ:
                return(ExpressionType.OrAssign);

            case OPERATOR.LSHIFTEQ:
                return(ExpressionType.LeftShiftAssign);

            case OPERATOR.RSHIFTEQ:
                return(ExpressionType.RightShiftAssign);

            case OPERATOR.QUESTION:
                //return ExpressionType;
                break;

            case OPERATOR.VALORDEF:
                //return ExpressionType;
                break;

            case OPERATOR.LOGOR:
                return(ExpressionType.Or);

            case OPERATOR.LOGAND:
                return(ExpressionType.And);

            case OPERATOR.BITOR:
            //return ExpressionType;
            case OPERATOR.BITXOR:
            //return ExpressionType;
            case OPERATOR.BITAND:
                //return ExpressionType;
                break;

            case OPERATOR.EQ:
                return(ExpressionType.Equal);

            case OPERATOR.NEQ:
                return(ExpressionType.NotEqual);

            case OPERATOR.LT:
                return(ExpressionType.LessThan);

            case OPERATOR.LE:
                return(ExpressionType.LessThanOrEqual);

            case OPERATOR.GT:
                return(ExpressionType.GreaterThan);

            case OPERATOR.GE:
                return(ExpressionType.GreaterThanOrEqual);

            case OPERATOR.IS:
                return(ExpressionType.TypeIs);

            case OPERATOR.AS:
                return(ExpressionType.TypeAs);

            case OPERATOR.LSHIFT:
                return(ExpressionType.LeftShift);

            case OPERATOR.RSHIFT:
                return(ExpressionType.RightShift);

            case OPERATOR.ADD:
                return(ExpressionType.Add);

            case OPERATOR.SUB:
                return(ExpressionType.Subtract);

            case OPERATOR.MUL:
                return(ExpressionType.Multiply);

            case OPERATOR.DIV:
                return(ExpressionType.Divide);

            case OPERATOR.MOD:
                return(ExpressionType.Modulo);

            case OPERATOR.NOP:
                //return ExpressionType;
                break;

            case OPERATOR.UPLUS:
                return(ExpressionType.UnaryPlus);

            case OPERATOR.NEG:
                return(ExpressionType.Negate);

            case OPERATOR.BITNOT:
                return(ExpressionType.OnesComplement);

            case OPERATOR.LOGNOT:
                return(ExpressionType.Not);

            case OPERATOR.PREINC:
                return(ExpressionType.PreIncrementAssign);

            case OPERATOR.PREDEC:
                return(ExpressionType.PreDecrementAssign);

            case OPERATOR.TYPEOF:
            //return ExpressionType;
            case OPERATOR.SIZEOF:
            //return ExpressionType;
            case OPERATOR.CHECKED:
            //return ExpressionType;
            case OPERATOR.UNCHECKED:
            //return ExpressionType;
            case OPERATOR.MAKEREFANY:
            //return ExpressionType;
            case OPERATOR.REFVALUE:
            //return ExpressionType;
            case OPERATOR.REFTYPE:
            //return ExpressionType;
            case OPERATOR.ARGS:
            //return ExpressionType;
            case OPERATOR.CAST:
            //return ExpressionType;
            case OPERATOR.INDIR:
            //return ExpressionType;
            case OPERATOR.ADDR:
            //return ExpressionType;
            case OPERATOR.COLON:
            //return ExpressionType;
            case OPERATOR.THIS:
            //return ExpressionType;
            case OPERATOR.BASE:
            //return ExpressionType;
            case OPERATOR.NULL:
            //return ExpressionType;
            case OPERATOR.TRUE:
            //return ExpressionType;
            case OPERATOR.FALSE:
            //return ExpressionType;
            case OPERATOR.CALL:
            //return ExpressionType;
            case OPERATOR.DEREF:
            //return ExpressionType;
            case OPERATOR.PAREN:
                //return ExpressionType;
                break;

            case OPERATOR.POSTINC:
                return(ExpressionType.PostIncrementAssign);

            case OPERATOR.POSTDEC:
                return(ExpressionType.PostDecrementAssign);

            case OPERATOR.DOT:
            //return ExpressionType;
            case OPERATOR.IMPLICIT:
            //return ExpressionType;
            case OPERATOR.EXPLICIT:
            //return ExpressionType;
            case OPERATOR.EQUALS:
            //return ExpressionType;
            case OPERATOR.COMPARE:
            //return ExpressionType;
            case OPERATOR.DEFAULT:
                //return ExpressionType;
                break;

            // CS3
            case OPERATOR.LAMBDA:
                return(ExpressionType.Lambda);

            default:
                break;
            }
            DebugUtil.Assert(false);
            return((ExpressionType)(-1));
        }
Пример #12
0
        private bool dontDoHashes    = false;   // m_bDontDoHashes      : 1;

        //------------------------------------------------------------
        // CAsmLink Constructor
        //
        /// <summary></summary>
        /// <param name="cntr"></param>
        //------------------------------------------------------------
        internal CAsmLink(CController cntr)
        {
            DebugUtil.Assert(cntr != null);
            this.controller = cntr;
        }
Пример #13
0
 //------------------------------------------------------------
 // CAsmLink.PreCloseAssembly
 //------------------------------------------------------------
 virtual internal bool PreCloseAssembly(uint AssemblyID)
 {
     DebugUtil.Assert(this.inited && !this.preClosed);
     return(true);
 }
Пример #14
0
        //------------------------------------------------------------
        // CParser.ParseObjectInitializer
        //
        /// <summary></summary>
        /// <param name="newNode"></param>
        //------------------------------------------------------------
        internal void ParseObjectInitializer(NEWNODE newNode)
        {
            DebugUtil.Assert(CurrentTokenID() == TOKENID.OPENCURLY);
            NextToken();

            DECLSTMTNODE stmtNode = AllocNode(NODEKIND.DECLSTMT, newNode) as DECLSTMTNODE;

            CListMaker list  = new CListMaker(this);
            int        comma = -1;

            while (
                CurrentTokenID() != TOKENID.CLOSECURLY &&
                CurrentTokenID() != TOKENID.ENDFILE)
            {
                if (CurrentTokenID() == TOKENID.IDENTIFIER &&
                    PeekToken(1) == TOKENID.EQUAL)
                {
                    list.Add(
                        ParseVariableDeclarator(
                            stmtNode,
                            stmtNode,
                            (uint)PARSEDECLFLAGS.LOCAL,
                            false,  // isFirst,
                            -1),
                        comma);
                }
                else
                {
                    Error(CSCERRID.ERR_InvalidInitializerDeclarator);

                    TOKENID tid = CurrentTokenID();
                    while (
                        tid != TOKENID.COMMA &&
                        tid != TOKENID.CLOSECURLY &&
                        tid != TOKENID.ENDFILE)
                    {
                        NextToken();
                        tid = CurrentTokenID();
                    }
                }

                if (CurrentTokenID() != TOKENID.COMMA)
                {
                    break;
                }
                comma = CurrentTokenIndex();
                NextToken();
            }
            Eat(TOKENID.CLOSECURLY);

            stmtNode.VariablesNode = list.GetList(stmtNode);
            newNode.InitialNode    = stmtNode;
            newNode.Flags         |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;

            if (newNode.ParentNode != null &&
                newNode.ParentNode.Kind == NODEKIND.VARDECL)
            {
                VARDECLNODE vdNode = newNode.ParentNode as VARDECLNODE;
                if (vdNode != null)
                {
                    newNode.Flags   |= NODEFLAGS.NEW_IN_VARDECL;
                    vdNode.NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;
                }
            }
            else if (newNode.ParentNode != null &&
                     newNode.ParentNode.Kind == NODEKIND.BINOP &&
                     newNode.Operator == OPERATOR.ASSIGN)
            {
                VARDECLNODE vdNode = newNode.ParentNode.ParentNode as VARDECLNODE;
                if (vdNode != null)
                {
                    newNode.Flags   |= NODEFLAGS.NEW_IN_VARDECL;
                    vdNode.NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;
                }
            }

            BASENODE node = newNode.ParentNode;

            while (node != null && !node.IsStatement)
            {
                node = node.ParentNode;
            }
            if (node != null)
            {
                (node as STATEMENTNODE).NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER;
            }
        }
Пример #15
0
        //------------------------------------------------------------
        // ConsoleOutput.PrettyPrint (2)
        //
        /// <summary></summary>
        /// <param name="builder"></param>
        /// <param name="text"></param>
        /// <param name="indent"></param>
        //------------------------------------------------------------
        protected void PrettyPrint(
            StringBuilder builder,
            string text,
            int indent)
        {
            // 100 characters should be more than large enough for any indent
            DebugUtil.Assert(indent >= 0 && indent <= 100);

            if (String.IsNullOrEmpty(text))
            {
                return;
            }

            int width = this.ConsoleWidth - indent - 1;

            if (width <= 0)
            {
                builder.Append(text);
                return;
            }

            // the first line

            int count = indent;

            if (builder.Length >= indent)
            {
                builder.Append(System.Environment.NewLine);
                builder.Append(' ', count);
            }
            else
            {
                count -= builder.Length;
                builder.Append(' ', count);
            }

            if (text.Length <= width)
            {
                builder.Append(text);
                builder.Append(System.Environment.NewLine);
                return;
            }

            builder.Append(text.Substring(0, width));
            builder.Append(System.Environment.NewLine);
            text = text.Substring(width);

            while (true)
            {
                builder.Append(' ', indent);

                if (text.Length <= width)
                {
                    builder.Append(text);
                    builder.Append(System.Environment.NewLine);
                    return;
                }

                builder.Append(text.Substring(0, width));
                builder.Append(System.Environment.NewLine);
                text = text.Substring(width);
            }
        }
Пример #16
0
        //------------------------------------------------------------
        // FUNCBREC.BindCollectionInitializer
        //
        /// <summary></summary>
        /// <param name="newNode"></param>
        /// <param name="typeSym"></param>
        /// <param name="locVarSym"></param>
        /// <param name="objectExpr"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal EXPR BindCollectionInitializer(
            NEWNODE newNode,
            BASENODE elementsNode,
            TYPESYM typeSym,
            LOCVARSYM locVarSym,
            EXPR leftExpr,
            EXPR rightExpr,
            StatementListBuilder builder)
        {
            DebugUtil.Assert(newNode != null && typeSym != null && builder != null);
            DebugUtil.Assert(locVarSym != null || leftExpr != null || rightExpr != null);

            string addMethName = Compiler.NameManager.GetPredefinedName(PREDEFNAME.ADD);

            //--------------------------------------------------------
            // typeSym should implement IEnumerable.
            //--------------------------------------------------------
            AGGTYPESYM enumerableSym = HasIEnumerable(typeSym);

            if (enumerableSym == null)
            {
                Compiler.Error(
                    newNode.TypeNode,
                    CSCERRID.ERR_CollectInitRequiresIEnumerable,
                    new ErrArg(typeSym));
                return(rightExpr);
            }

            TYPESYM   paramTypeSym = null;
            TypeArray typeArgs     = enumerableSym.TypeArguments;

            if (typeArgs != null && typeArgs.Count > 0)
            {
                DebugUtil.Assert(typeArgs.Count == 1);
                paramTypeSym = typeArgs[0];
            }
            else
            {
                paramTypeSym
                    = Compiler.GetReqPredefAgg(PREDEFTYPE.OBJECT, true).GetThisType();
                if (typeArgs == null)
                {
                    typeArgs = new TypeArray();
                }
                typeArgs.Add(paramTypeSym);
                typeArgs = Compiler.MainSymbolManager.AllocParams(typeArgs);
            }

            BindFlagsEnum bindFlags   = BindFlagsEnum.RValueRequired;
            string        localFormat = "<{0}><{1}>__local";

            //--------------------------------------------------------
            // Bind the local variable.
            //--------------------------------------------------------
            if (leftExpr == null)
            {
                if (locVarSym == null)
                {
                    string locName
                        = String.Format(localFormat, typeSym.Name, (this.localCount)++);

                    locVarSym = Compiler.LocalSymbolManager.CreateLocalSym(
                        SYMKIND.LOCVARSYM,
                        locName,
                        this.currentScopeSym) as LOCVARSYM;
                    locVarSym.TypeSym             = typeSym;
                    locVarSym.LocSlotInfo.HasInit = true;
                    locVarSym.DeclTreeNode        = newNode;

                    StoreInCache(newNode, locName, locVarSym, null, true);
                }

                leftExpr = BindToLocal(
                    newNode,
                    locVarSym,
                    bindFlags | BindFlagsEnum.MemberSet);
            }

            //--------------------------------------------------------
            // If objectExpr is not null, assign it to the local variable.
            //--------------------------------------------------------
            if (rightExpr != null)
            {
                EXPR assignLocExpr = BindAssignment(
                    newNode,
                    leftExpr,
                    rightExpr,
                    false);

                builder.Add(SetNodeStmt(newNode, MakeStmt(newNode, assignLocExpr, 0)));
            }

            //--------------------------------------------------------
            // Get "Add" method.
            //--------------------------------------------------------
            MemberLookup mem = new MemberLookup();

            if (!mem.Lookup(
                    Compiler,
                    typeSym,
                    leftExpr,
                    this.parentDeclSym,
                    addMethName,
                    0,
                    MemLookFlagsEnum.UserCallable))
            {
                Compiler.Error(
                    newNode.TypeNode,
                    CSCERRID.ERR_NoSuchMember,
                    new ErrArg(typeSym),
                    new ErrArg("Add"));
                return(NewError(newNode, null));
            }
            if (mem.FirstSym == null || !mem.FirstSym.IsMETHSYM)
            {
                return(NewError(newNode, null));
            }

            TypeArray typeGroup = mem.GetAllTypes();

            EXPRMEMGRP grpExpr = NewExpr(
                newNode,
                EXPRKIND.MEMGRP,
                Compiler.MainSymbolManager.MethodGroupTypeSym) as EXPRMEMGRP;

            grpExpr.Name                = addMethName;
            grpExpr.SymKind             = SYMKIND.METHSYM;
            grpExpr.TypeArguments       = BSYMMGR.EmptyTypeArray;
            grpExpr.ParentTypeSym       = typeSym;
            grpExpr.MethPropSym         = null;
            grpExpr.ObjectExpr          = leftExpr;
            grpExpr.ContainingTypeArray = typeGroup;
            grpExpr.Flags              |= EXPRFLAG.USERCALLABLE;

            //--------------------------------------------------------
            // Add each value.
            //--------------------------------------------------------
            DebugUtil.Assert(newNode.InitialNode != null);
#if false
            BASENODE node = null;
            switch (newNode.InitialNode.Kind)
            {
            case NODEKIND.DECLSTMT:
                node = (newNode.InitialNode as DECLSTMTNODE).VariablesNode;
                break;

            case NODEKIND.UNOP:
                node = (newNode.InitialNode as UNOPNODE).Operand;
                break;

            default:
                DebugUtil.Assert(false);
                break;
            }
#endif
            BASENODE node = elementsNode;
            while (node != null)
            {
                BASENODE elementNode;
                if (node.Kind == NODEKIND.LIST)
                {
                    elementNode = node.AsLIST.Operand1;
                    node        = node.AsLIST.Operand2;
                }
                else
                {
                    elementNode = node;
                    node        = null;
                }

                //----------------------------------------------------
                // Bind the elements
                //----------------------------------------------------
                EXPR elementExpr = BindExpr(
                    elementNode,
                    BindFlagsEnum.RValueRequired);

                //----------------------------------------------------
                // Add the elements
                //----------------------------------------------------
                EXPR addExpr = BindGrpToArgs(newNode, bindFlags, grpExpr, elementExpr);

                if (addExpr != null)
                {
                    builder.Add(SetNodeStmt(newNode, MakeStmt(newNode, addExpr, 0)));
                }
            }

            return(leftExpr);
        }
Пример #17
0
        //------------------------------------------------------------
        // FUNCBREC.CreateAutoImplementedSetAccessor
        //
        /// <summary></summary>
        /// <param name="methodSym"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal EXPR CreateAutoImplementedSetAccessor(METHSYM methodSym)
        {
            CreateNewScope();
            SCOPESYM scopeSym = this.currentScopeSym;

            this.currentScopeSym.ScopeFlags = SCOPEFLAGS.NONE;

            this.currentBlockExpr          = NewExprBlock(treeNode);
            this.currentBlockExpr.ScopeSym = this.currentScopeSym;

            //--------------------------------------------------------
            // Back filed
            //--------------------------------------------------------
            SymWithType fieldSwt  = new SymWithType();
            AGGTYPESYM  parentAts = methodSym.ParentAggSym.GetThisType();

            fieldSwt.Set(
                methodSym.PropertySym.BackFieldSym,
                parentAts);

            EXPR fieldExpr = BindToField(
                null,
                BindThisImplicit(null),
                FieldWithType.Convert(fieldSwt),
                BindFlagsEnum.RValueRequired);

            //--------------------------------------------------------
            // Parameter "value"
            //--------------------------------------------------------
            // The SYM instance of parameter "value" is a LOCVARSYM instance,
            // and is created in CLSDREC.FillMethInfoCommon.
            LOCVARSYM locSym = Compiler.LocalSymbolManager.LookupLocalSym(
                Compiler.NameManager.GetPredefinedName(PREDEFNAME.VALUE),
                this.OuterScopeSym,
                SYMBMASK.LOCVARSYM) as LOCVARSYM;

            DebugUtil.Assert(locSym != null);

            SymWithType valueSwt = new SymWithType();

            valueSwt.Set(locSym, null);

            EXPR valueExpr = BindToLocal(null, locSym, BindFlagsEnum.RValueRequired);

            //--------------------------------------------------------
            // BackField = value
            //--------------------------------------------------------
            EXPR assignExpr = NewExprBinop(
                null,
                EXPRKIND.ASSG,
                fieldExpr.TypeSym,
                fieldExpr,
                valueExpr);

            //--------------------------------------------------------
            // Statement
            //--------------------------------------------------------
            EXPRSTMTAS stmt = NewExpr(null, EXPRKIND.STMTAS, null) as EXPRSTMTAS;

            stmt.Expr = assignExpr;

            //--------------------------------------------------------
            // Block
            //--------------------------------------------------------
            this.currentBlockExpr.StatementsExpr = stmt;
            EXPRBLOCK blockExpr = this.currentBlockExpr;

            this.currentBlockExpr = blockExpr.OwingBlockExpr;

            CloseScope();

            CorrectAnonMethScope(blockExpr.ScopeSym);

            return(blockExpr);
        }
Пример #18
0
 //------------------------------------------------------------
 // ERRLOC.SetEndInternal (1)
 //
 /// <summary>
 /// only set the end if it is on the same line
 /// as we want to report the error on
 /// </summary>
 /// <param name="ld"></param>
 /// <param name="node"></param>
 //------------------------------------------------------------
 private void SetEndInternal(LEXDATA ld, BASENODE node)
 {
     DebugUtil.Assert(!startPos.IsUninitialized);
     SetEndInternal(ld, (int)node.TokenIndex, 0);
 }
Пример #19
0
        //------------------------------------------------------------
        // SecurityUtil.AppendSecurityAttribute (2)
        //
        /// <summary>
        ///
        /// </summary>
        /// <param name="secAttrType"></param>
        /// <param name="positionalArgs"></param>
        /// <param name="argNames"></param>
        /// <param name="argValues"></param>
        /// <param name="permissionSets"></param>
        /// <param name="excp"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        public static bool AppendSecurityAttribute(
            Type secAttrType,
            Object[] positionalArgs,
            List <string> fieldNames,
            List <object> fieldValues,
            List <string> propertyNames,
            List <object> propertyValues,
            Dictionary <SecurityAction, PermissionSet> permissionSets,
            out Exception excp)
        {
            excp = null;
            if (permissionSets == null)
            {
                return(false);
            }
            if (secAttrType == null ||
                positionalArgs == null || positionalArgs.Length == 0)
            {
                return(false);
            }

            int fieldCount = fieldNames != null ? fieldNames.Count : 0;

            if (fieldCount != (fieldValues != null ? fieldValues.Count : 0))
            {
                return(false);
            }
            int propertyCount = propertyNames != null ? propertyNames.Count : 0;

            if (propertyCount != (propertyValues != null ? propertyValues.Count : 0))
            {
                return(false);
            }

            SecurityAction secAction;

            try
            {
                secAction = (SecurityAction)positionalArgs[0];
            }
            catch (InvalidCastException ex)
            {
                excp = ex;
                return(false);
            }

            //switch (secAction)
            //{
            //    case SecurityAction.Assert:
            //    case SecurityAction.Demand:
            //    case SecurityAction.Deny:
            //    case SecurityAction.InheritanceDemand:
            //    case SecurityAction.LinkDemand:
            //    case SecurityAction.PermitOnly:
            //    case SecurityAction.RequestMinimum:
            //    case SecurityAction.RequestOptional:
            //    case SecurityAction.RequestRefuse:
            //        break;
            //    default:
            //        return false;
            //}

            // Create the attribute instance with its positional arguments

            Object activatedObj = ReflectionUtil.CreateInstance(
                secAttrType,
                positionalArgs,
                out excp);

            if (activatedObj == null || excp != null)
            {
                return(false);
            }

            // Assign the named arguments to the fields.

            Object[] narg = new Object[1];

            if (fieldCount > 0)
            {
                for (int i = 0; i < fieldCount; ++i)
                {
                    narg[0] = fieldValues[i];
                    if (!ReflectionUtil.InvokeMember(
                            secAttrType,
                            fieldNames[i],
                            BindingFlags.SetField,
                            null,
                            activatedObj,
                            narg,
                            out excp))
                    {
                        return(false);
                    }
                }
            }

            // Assign the named arguments to the properties.

            if (propertyCount > 0)
            {
                for (int i = 0; i < propertyCount; ++i)
                {
                    narg[0] = propertyValues[i];
                    if (!ReflectionUtil.InvokeMember(
                            secAttrType,
                            propertyNames[i],
                            BindingFlags.SetProperty,
                            null,
                            activatedObj,
                            narg,
                            out excp))
                    {
                        return(false);
                    }
                }
            }

            SecurityAttribute secAttr = activatedObj as SecurityAttribute;

            if (secAttr == null)
            {
                return(false);
            }

            IPermission secPerm = secAttr.CreatePermission();

            if (secAttr != null)
            {
                PermissionSet permSet = null;
                if (!permissionSets.TryGetValue(secAction, out permSet))
                {
                    permSet = new PermissionSet(null);
                    permissionSets.Add(secAction, permSet);
                }
                else if (permSet == null)
                {
                    permSet = new PermissionSet(null);
                    permissionSets[secAction] = permSet;
                }
                DebugUtil.Assert(permSet != null);

                permSet.AddPermission(secPerm);
                return(true);
            }
            return(false);
        }
Пример #20
0
 //------------------------------------------------------------
 // CSourceData Constructor (private)
 //
 /// <summary>
 /// This is private. Call CreateInstance method to create an instance.
 /// </summary>
 /// <param name="module"></param>
 //------------------------------------------------------------
 private CSourceData(CSourceModuleBase module)
 {
     DebugUtil.Assert(module != null);
     sourceModuleBase = module;
 }
Пример #21
0
        //------------------------------------------------------------
        // SecurityUtil.AppendSecurityAttribute (1)
        //
        /// <summary>
        ///
        /// </summary>
        /// <param name="secAttrType"></param>
        /// <param name="positionalArgs"></param>
        /// <param name="argNames"></param>
        /// <param name="argValues"></param>
        /// <param name="permissionSets"></param>
        /// <param name="excp"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        public static bool AppendSecurityAttribute(
            Type secAttrType,
            Object[] positionalArgs,
            String[] argNames,
            Object[] argValues,
            Dictionary <SecurityAction, PermissionSet> permissionSets,
            out Exception excp)
        {
            excp = null;
            if (permissionSets == null)
            {
                return(false);
            }
            if (secAttrType == null ||
                positionalArgs == null || positionalArgs.Length == 0)
            {
                return(false);
            }

            SecurityAction secAction;

            try
            {
                secAction = (SecurityAction)positionalArgs[0];
            }
            catch (InvalidCastException ex)
            {
                excp = ex;
                return(false);
            }

            //switch (secAction)
            //{
            //    case SecurityAction.Assert:
            //    case SecurityAction.Demand:
            //    case SecurityAction.Deny:
            //    case SecurityAction.InheritanceDemand:
            //    case SecurityAction.LinkDemand:
            //    case SecurityAction.PermitOnly:
            //    case SecurityAction.RequestMinimum:
            //    case SecurityAction.RequestOptional:
            //    case SecurityAction.RequestRefuse:
            //        break;
            //    default:
            //        return false;
            //}

            // Create the attribute instance with its positional arguments

            Object activatedObj = ReflectionUtil.CreateInstance(
                secAttrType,
                positionalArgs,
                out excp);

            if (activatedObj == null || excp != null)
            {
                return(false);
            }

            // Assign the named arguments to the fields or properties.

            int namedCount = 0;

            if (argNames != null && (namedCount = argNames.Length) > 0)
            {
                if (argValues == null || argValues.Length != namedCount)
                {
                    return(false);
                }
                Object[] narg = new Object[1];

                for (int i = 0; i < argNames.Length; ++i)
                {
                    string name = argNames[i];
                    if (String.IsNullOrEmpty(name))
                    {
                        return(false);
                    }

                    MemberInfo[] membs = secAttrType.GetMember(name);
                    if (membs.Length != 1)
                    {
                        return(false);
                    }

                    narg[0] = argValues[i];
                    MemberTypes  membType  = membs[0].MemberType;
                    BindingFlags bindFlags = 0;
                    if (membType == MemberTypes.Property)
                    {
                        bindFlags = BindingFlags.SetProperty;
                    }
                    else if (membType == MemberTypes.Field)
                    {
                        bindFlags = BindingFlags.SetField;
                    }
                    else
                    {
                        return(false);
                    }

                    if (!ReflectionUtil.InvokeMember(
                            secAttrType,
                            name,
                            bindFlags,
                            null,
                            activatedObj,
                            narg,
                            out excp))
                    {
                        return(false);
                    }
                }
            }

            SecurityAttribute secAttr = activatedObj as SecurityAttribute;

            if (secAttr == null)
            {
                return(false);
            }

            IPermission secPerm = secAttr.CreatePermission();

            if (secAttr != null)
            {
                PermissionSet permSet = null;
                if (!permissionSets.TryGetValue(secAction, out permSet))
                {
                    permSet = new PermissionSet(null);
                    permissionSets.Add(secAction, permSet);
                }
                else if (permSet == null)
                {
                    permSet = new PermissionSet(null);
                    permissionSets[secAction] = permSet;
                }
                DebugUtil.Assert(permSet != null);

                permSet.AddPermission(secPerm);
                return(true);
            }
            return(false);
        }
Пример #22
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubSave
        //
        /// <summary>
        /// Fill in the given slot (iexpr) of the NubInfo appropriately.
        /// If exprSrc is a constant (possibly with side effects),
        /// put the side effects in nin.rgexprPre[iexpr] and the constant value in nin.rgexprVal[iexpr].
        /// Otherwise, construct an expr to save the value of exprSrc in a temp,
        /// an expr to load the temp and an expr to free the temp.
        /// Store these in the appropriate places in the NubInfo.
        /// If fLift is true, the value saved in the temp will have at most one level of Nullable.
        /// </summary>
        /// <param name="srcExpr"></param>
        /// <param name="nubInfo"></param>
        /// <param name="exprIndex"></param>
        /// <param name="fLift"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private bool BindNubSave(EXPR srcExpr, ref NubInfo nubInfo, int exprIndex, bool fLift)
        {
            DebugUtil.Assert(exprIndex == 0 || exprIndex == 1);
            DebugUtil.Assert(
                nubInfo.PreExpr[exprIndex] == null &&
                nubInfo.PostExpr[exprIndex] == null &&
                nubInfo.ValueExpr[exprIndex] == null &&
                nubInfo.TmpExpr[exprIndex] == null &&
                nubInfo.ConditionExpr[exprIndex] == null);

            // If we're lifting the expr and it's a new T?(t), just operate on t. The caller should have
            // already taken care of calling StripNubCtor!
            DebugUtil.Assert(!srcExpr.TypeSym.IsNUBSYM || !fLift || !IsNubCtor(srcExpr));

            // Check for an EXPRKIND.CONSTANT or EXPRKIND.ZEROINIT inside EXPRKIND.SEQUENCE and EXPRKIND.SEQREV exprs.
            EXPR constExpr = srcExpr.GetConst();

            if (constExpr != null)
            {
                DebugUtil.Assert(constExpr.Kind == EXPRKIND.CONSTANT || constExpr.Kind == EXPRKIND.ZEROINIT);
                if (constExpr != srcExpr)
                {
                    // Keep the side effects.
                    nubInfo.PreExpr[exprIndex] = srcExpr;
                }
                if (!constExpr.TypeSym.IsNUBSYM || !fLift)
                {
                    nubInfo.TmpExpr[exprIndex] = constExpr;
                }
                else
                {
                    nubInfo.TmpExpr[exprIndex] = NewExprZero(
                        srcExpr.TreeNode, constExpr.TypeSym.StripAllButOneNub());
                }
                return(false);
            }

            if (srcExpr.TypeSym.IsNUBSYM && fLift)
            {
                while (srcExpr.TypeSym.ParentSym.IsNUBSYM)
                {
                    srcExpr = BindNubGetValOrDef(srcExpr.TreeNode, srcExpr);
                }
            }

            if (srcExpr.Kind == EXPRKIND.LDTMP)
            {
                // The thing is already in a temp, no need to put it in another.
                nubInfo.PreExpr[exprIndex] = srcExpr;
                nubInfo.TmpExpr[exprIndex] = srcExpr;
                return(true);
            }

            // Create the temp.
            EXPRSTTMP   tmpStExpr   = NewExpr(srcExpr.TreeNode, EXPRKIND.STTMP, srcExpr.TypeSym) as EXPRSTTMP;
            EXPRLDTMP   tmpLdExpr   = NewExpr(srcExpr.TreeNode, EXPRKIND.LDTMP, srcExpr.TypeSym) as EXPRLDTMP;
            EXPRFREETMP tmpFreeExpr = NewExpr(srcExpr.TreeNode, EXPRKIND.FREETMP, srcExpr.TypeSym) as EXPRFREETMP;

            tmpStExpr.SourceExpr = srcExpr;
            tmpStExpr.Flags     |= EXPRFLAG.ASSGOP;
            tmpLdExpr.TmpExpr    = tmpStExpr;
            tmpFreeExpr.TmpExpr  = tmpStExpr;
            tmpFreeExpr.Flags   |= EXPRFLAG.ASSGOP;

            nubInfo.PreExpr[exprIndex]  = tmpStExpr;
            nubInfo.PostExpr[exprIndex] = tmpFreeExpr;
            nubInfo.TmpExpr[exprIndex]  = tmpLdExpr;

            return(true);
        }
Пример #23
0
        // The following methods comprise the error handling/COMPILER-to-CController hosting

        //------------------------------------------------------------
        // CController.CreateError (1)
        //
        /// <summary>
        /// <para>This function creates a CError object from the given information.
        /// The CError object is created with no location information.
        /// The CError object is returned with a ref count of 0.</para>
        /// </summary>
        /// <param name="errorId">Error ID.</param>
        /// <param name="args">Arguments for error message.</param>
        /// <param name="error">A created CError instance will be set.</param>
        /// <param name="warnOverride">if true, treats a error as a warning.</param>
        /// <returns>if failed to create a instance, return false.</returns>
        /// <remarks>
        /// <para>If "warnOverride" is true (defaults to false), and this error is usually
        /// an error (not warning or fatal), then the error is wrapped with warning WRN_ErrorOverride</para>
        /// </remarks>
        //------------------------------------------------------------
        internal bool CreateError(
            CSCERRID errorId,
            ErrArg[] args,
            out CError error,
            bool warnOverride)  // = false);
        {
            error = null;
            // Make some assertions...
            DebugUtil.Assert(errorId > 0 && errorId < CSCERRID.ERR_COUNT);
            DebugUtil.Assert(errorId != CSCERRID.WRN_ErrorOverride);

            CError errorObject = null;
            int    errNo;
            int    level1, level2;

            // when errorId is invalid, or has no level, return false;
            if (!CSCErrorInfo.Manager.GetInfo(errorId, out errNo, out level1))
            {
                goto LERROR;
            }

            if (level1 == 0 && warnOverride)
            {
                // If errorId is of ERROR and should treat it as WARNING,
                // and if CSCERRID.WRN_ErrorOverride is lower than optionData.WarnLevel,
                // return false.
                if (CSCErrorInfo.Manager.GetWarningLevel(CSCERRID.WRN_ErrorOverride, out level2))
                {
                    if (!CheckDisplayWarning(CSCERRID.WRN_ErrorOverride, level2))
                    {
                        return(true);
                    }
                }
            }
            else
            {
                // Clear this bit (since we clearly aren't overriding an error to a warning)
                warnOverride = false;

                // If it's a warning, does it meet the warning level criteria?
                if (level1 > 0 && !CheckDisplayWarning(errorId, level1))
                {
                    return(true);
                }
            }

            // Create a CError instance and initialize it.
            errorObject = new CError();
            if (errorObject == null || !errorObject.Initialize((CSCERRID)errorId, args))
            {
                goto LERROR;
            }

            // Do we need to wrap this Error in a warning?
            if (warnOverride == true)
            {
                DebugUtil.Assert(errorObject.Kind == ERRORKIND.ERROR);
                if (!errorObject.Initialize(
                        CSCERRID.WRN_ErrorOverride,
                        new ErrArg(errorObject.Text),
                        new ErrArg(errorObject.ErrorID)))
                {
                    goto LERROR;
                }
            }

            // Now check to see if we need to promote this warning to an error
            if (errorObject.Kind == ERRORKIND.WARNING &&
                this.OptionManager.IsWarnAsError(errorObject.ErrorID) &&
                !errorObject.WarnAsError())
            {
                goto LERROR;
            }
            error = errorObject;
            return(true);

LERROR:
            if (errorObject != null &&
                !String.IsNullOrEmpty(errorObject.Text))
            {
                OnCatastrophicError(errorObject.Text);
            }
            else
            {
                OnCatastrophicError("CController.CreateError");
            }
            error = null;
            return(false);
        }
Пример #24
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubCondValBin
        //
        /// <summary>
        /// <para>Fill in the NubInfo for a unary or binary operator lifting.</para>
        /// <para>(In sscli, liftFlags has default value LiftFlags::LiftBoth.)</para>
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="expr1"></param>
        /// <param name="expr2"></param>
        /// <param name="nubInfo"></param>
        /// <param name="liftFlags"></param>
        //------------------------------------------------------------
        private void BindNubCondValBin(
            BASENODE treeNode,
            EXPR expr1,
            EXPR expr2,
            ref NubInfo nubInfo,
            LiftFlagsEnum liftFlags)    // = LiftFlags::LiftBoth
        {
            DebugUtil.Assert((liftFlags & (LiftFlagsEnum.Lift1 | LiftFlagsEnum.Lift2)) != 0);
            DebugUtil.Assert(expr1 != null);
            DebugUtil.Assert(expr2 != null || (liftFlags & LiftFlagsEnum.Lift1) != 0);

            nubInfo.Init();

            bool[] rgfLift = { false, false };
            rgfLift[0] = ((liftFlags & LiftFlagsEnum.Lift1) != 0);
            rgfLift[1] = expr2 != null && ((liftFlags & LiftFlagsEnum.Lift2) != 0);

            EXPR[] rgexpr = { null, null };
            rgexpr[0] = rgfLift[0] ? StripNubCtor(expr1) : expr1;
            rgexpr[1] = rgfLift[1] ? StripNubCtor(expr2) : expr2;

            if ((!rgfLift[0] || !rgexpr[0].TypeSym.IsNUBSYM) && (!rgfLift[1] || !rgexpr[1].TypeSym.IsNUBSYM))
            {
                // All lifted params can't be null so we don't need temps.
                nubInfo.ValueExpr[0]    = rgexpr[0];
                nubInfo.ValueExpr[1]    = rgexpr[1];
                nubInfo.IsActive        = true;
                nubInfo.IsAlwaysNonNull = true;
                return;
            }

            // Optimization: if they are the same local then we only need one temp.
            if (rgexpr[1] != null &&
                rgexpr[0].Kind == EXPRKIND.LOCAL &&
                rgexpr[1].Kind == EXPRKIND.LOCAL &&
                (rgexpr[0] as EXPRLOCAL).LocVarSym == (rgexpr[1] as EXPRLOCAL).LocVarSym &&
                rgfLift[0] == rgfLift[1])
            {
                BindNubSave(rgexpr[0], ref nubInfo, 0, rgfLift[0]);
                DebugUtil.Assert(nubInfo.TmpExpr[0].Kind == EXPRKIND.LDTMP);
                nubInfo.TmpExpr[1] = nubInfo.TmpExpr[0];
                nubInfo.IsSameTemp = true;
            }
            else
            {
                BindNubSave(rgexpr[0], ref nubInfo, 0, rgfLift[0]);
                if (rgexpr[1] != null)
                {
                    BindNubSave(rgexpr[1], ref nubInfo, 1, rgfLift[1]);
                }
            }

            for (int iexpr = 0; iexpr < 2 && rgexpr[iexpr] != null; iexpr++)
            {
                if (!rgfLift[iexpr] || !nubInfo.TmpExpr[iexpr].TypeSym.IsNUBSYM)
                {
                    nubInfo.ValueExpr[iexpr] = nubInfo.TmpExpr[iexpr];
                    continue;
                }
                nubInfo.ValueExpr[iexpr] = BindNubGetValOrDef(treeNode, nubInfo.TmpExpr[iexpr]);
                DebugUtil.Assert(!nubInfo.ValueExpr[iexpr].TypeSym.IsNUBSYM);
                if (nubInfo.FConst(iexpr))
                {
                    nubInfo.IsNull[iexpr] = nubInfo.IsAlwaysNull = true;
                }
                else if (nubInfo.IsSameTemp && iexpr != 0)
                {
                    nubInfo.ConditionExpr[iexpr] = nubInfo.ConditionExpr[0];
                }
                else
                {
                    nubInfo.ConditionExpr[iexpr] = BindNubHasValue(treeNode, nubInfo.TmpExpr[iexpr], true);
                }
            }

            if (!nubInfo.IsAlwaysNull)
            {
                if (nubInfo.ConditionExpr[0] == null)
                {
                    nubInfo.CombinedConditionExpr = nubInfo.ConditionExpr[1];
                }
                else if (nubInfo.ConditionExpr[1] == null || nubInfo.IsSameTemp)
                {
                    nubInfo.CombinedConditionExpr = nubInfo.ConditionExpr[0];
                }
                else
                {
                    nubInfo.CombinedConditionExpr = NewExprBinop(
                        treeNode,
                        EXPRKIND.BITAND,
                        GetRequiredPredefinedType(PREDEFTYPE.BOOL),
                        nubInfo.ConditionExpr[0],
                        nubInfo.ConditionExpr[1]);
                }
            }
            else
            {
                // One of the operands is null so the result will always be null and we
                // don't need the temps.
                if (nubInfo.PreExpr[0] != null && nubInfo.PreExpr[0].Kind == EXPRKIND.STTMP)
                {
                    nubInfo.PreExpr[0] = (nubInfo.PreExpr[0] as EXPRSTTMP).SourceExpr;
                }
                if (nubInfo.PreExpr[1] != null && nubInfo.PreExpr[1].Kind == EXPRKIND.STTMP)
                {
                    nubInfo.PreExpr[1] = (nubInfo.PreExpr[1] as EXPRSTTMP).SourceExpr;
                }
                nubInfo.PostExpr[0] = null;
                nubInfo.PostExpr[1] = null;
            }

            nubInfo.IsActive = true;
            DebugUtil.Assert(nubInfo.CombinedConditionExpr != null || nubInfo.IsAlwaysNull);
        }
Пример #25
0
        //------------------------------------------------------------
        // FUNCBREC.BindBinaryOperator
        //
        // EXPR * BindIntBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindRealBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindDecBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindStrBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindShiftOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindBoolBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindBoolBitwiseOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindDelBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindEnumBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        //
        // EXPR * BindStrCmpOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindRefCmpOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindPtrBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        // EXPR * BindPtrCmpOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
        //
        /// <summary></summary>
        /// <param name="op"></param>
        /// <param name="tree"></param>
        /// <param name="ek"></param>
        /// <param name="flags"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private EXPR BindBinaryOperator(
            BindBinOpEnum op,
            BASENODE tree,
            EXPRKIND ek,
            EXPRFLAG flags,
            EXPR arg1,
            EXPR arg2)
        {
            switch (op)
            {
            case BindBinOpEnum.Integer:
                // Handles standard binary integer based operators.
                // EXPR * FUNCBREC::BindIntBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2)
                DebugUtil.Assert(
                    arg1.TypeSym.IsPredefined() &&
                    arg2.TypeSym.IsPredefined() &&
                    arg1.TypeSym.GetPredefType() == arg2.TypeSym.GetPredefType());
                return(BindIntOp(tree, ek, flags, arg1, arg2, arg1.TypeSym.GetPredefType()));

            case BindBinOpEnum.Real:
                // Handles standard binary floating point (float, double) based operators.
                // EXPR * FUNCBREC::BindRealBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2)
                DebugUtil.Assert(
                    arg1.TypeSym.IsPredefined() &&
                    arg2.TypeSym.IsPredefined() &&
                    arg1.TypeSym.GetPredefType() == arg2.TypeSym.GetPredefType());
                return(BindFloatOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.Decimal:
                return(BindDecBinOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.String:
                // Handles string concatenation.
                // EXPR * BindStrBinOp(BASENODE * tree, EXPRKIND ek, uint flags, EXPR * arg1, EXPR * arg2);
                DebugUtil.Assert(ek == EXPRKIND.ADD);
                DebugUtil.Assert(
                    arg1.TypeSym.IsPredefType(PREDEFTYPE.STRING) ||
                    arg2.TypeSym.IsPredefType(PREDEFTYPE.STRING));
                return(BindStringConcat(tree, arg1, arg2));

            case BindBinOpEnum.Shift:
                return(BindShiftOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.Bool:
                return(BindBoolBinOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.BoolBitwise:
                return(BindBoolBitwiseOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.Delegate:
                return(BindDelegateBinOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.Enum:
                return(BindEnumBinOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.StringCompare:
                return(BindStrCmpOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.ReferenceCompare:
                return(BindRefCmpOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.Pointer:
                return(BindPtrBinOp(tree, ek, flags, arg1, arg2));

            case BindBinOpEnum.PointerCompare:
                return(BindPtrCmpOp(tree, ek, flags, arg1, arg2));

            default:
                DebugUtil.Assert(false, "FUNCBREC.BindBinaryOperator");
                break;
            }
            return(null);
        }