예제 #1
0
        public RunScope Clone(bool?canBreak = null, bool?canContinue = null)
        {
            var scope = new RunScope(_ca, _funcDef, _funcOffset)
            {
                _returned    = _returned,
                _canBreak    = _canBreak,
                _canContinue = _canContinue,
                _suppressInitializedCheck = _suppressInitializedCheck
            };

            if (canBreak.HasValue)
            {
                scope._canBreak = canBreak.Value;
            }
            if (canContinue.HasValue)
            {
                scope._canContinue = canContinue.Value;
            }

            foreach (var v in _vars)
            {
                scope._vars[v.Key] = v.Value.Clone();
            }

            return(scope);
        }
예제 #2
0
        public void Merge(RunScope scope, bool promoteBreak = true, bool promoteContinue = true)
        {
            if (scope.Returned > _returned)
            {
                _returned = scope.Returned;
            }
            if (promoteBreak && scope.Breaked > _breaked)
            {
                _breaked = scope.Breaked;
            }
            if (promoteContinue && scope.Continued > _continued)
            {
                _continued = scope.Continued;
            }


            foreach (var myVar in _vars.Values)
            {
                Variable otherVar;
                if (scope._vars.TryGetValue(myVar.Name, out otherVar))
                {
                    if (scope.Returned != TriState.True)                        // Don't initialize variables if the branch returned before this point
                    {
                        if (otherVar.IsInitialized > myVar.IsInitialized)
                        {
                            myVar.IsInitialized = otherVar.IsInitialized;
                        }
                    }

                    if (otherVar.IsUsed)
                    {
                        myVar.IsUsed = true;
                    }
                }
            }
        }
예제 #3
0
        private void AnalyzeFunction(CodeModel.PreprocessorModel.LocalFunction func)
        {
            var body = _fullSource.Substring(func.StartPos, func.EndPos - func.StartPos);

            if (body.EndsWith("}"))
            {
                body = body.Substring(0, body.Length - 1);                                      // End pos is just after the closing brace
            }
            _read = new ReadParams
            {
                CodeAnalyzer = this,
                Code         = new CodeParser(body),
                FuncOffset   = func.StartPos,
                FuncDef      = func.Definition
            };

            _scope = new RunScope(this, func.Definition, func.StartPos);
            _stmts = new List <Statement>();

            // Parse the function body
            while (!_read.Code.EndOfFile)
            {
                var stmt = Statement.Read(_read);
                if (stmt == null)
                {
                    break;
                }
                _stmts.Add(stmt);
            }

            foreach (var arg in func.Arguments)
            {
                if (!string.IsNullOrEmpty(arg.Name))
                {
                    _scope.AddVariable(new Variable(arg, arg.Name, arg.DataType, Value.CreateUnknownFromDataType(arg.DataType), true, TriState.True, true));
                }
            }

            foreach (var v in func.Variables)
            {
                _scope.AddVariable(new Variable(v, v.Name, v.DataType, Value.CreateUnknownFromDataType(v.DataType), false, TriState.False, false));
            }

            foreach (var v in _prepModel.DefinitionProvider.GetGlobalFromFile <VariableDefinition>())
            {
                _scope.AddVariable(new Variable(v, v.Name, v.DataType, Value.CreateUnknownFromDataType(v.DataType), false, TriState.True, true));
            }

            foreach (var stmt in _stmts)
            {
                stmt.Execute(_scope);
            }

            if (func.Definition.DataType.ValueType != ValType.Void && _scope.Returned != TriState.True &&
                func.Definition.Name != "staticinitialize")
            {
                ReportErrorAbsolute(func.NameSpan, CAError.CA0017);                     // Function does not return a value.
            }

            foreach (var v in _scope.Variables)
            {
                if (!v.IsUsed)
                {
                    if (v.IsInitialized != TriState.False)
                    {
                        var def = v.Definition;
                        ReportErrorLocal(def.SourceFileName, new Span(def.SourceStartPos, def.SourceStartPos + def.Name.Length),
                                         false, null, CAError.CA0111, v.Name);                  // Variable '{0}' is assigned a value, but is never used.
                    }
                    else
                    {
                        var def = v.Definition;
                        ReportErrorLocal(def.SourceFileName, new Span(def.SourceStartPos, def.SourceStartPos + def.Name.Length),
                                         false, null, CAError.CA0112, v.Name);                  // Variable '{0}' is not used.
                    }
                }
            }
        }