Analysis: Add DollarInfo, VarPromotion, and move var clone at the right place when... 72/17572/2
Calixte DENIZET [Mon, 14 Dec 2015 13:17:56 +0000 (14:17 +0100)]
Change-Id: Ie1449ef530f9369f3076d3b6cac2a1193126fffb

33 files changed:
scilab/modules/ast/Makefile.am
scilab/modules/ast/Makefile.in
scilab/modules/ast/ast.vcxproj
scilab/modules/ast/ast.vcxproj.filters
scilab/modules/ast/includes/analysis/AnalysisVisitor.hxx
scilab/modules/ast/includes/analysis/Decorator.hxx
scilab/modules/ast/includes/analysis/DollarInfo.hxx
scilab/modules/ast/includes/analysis/OptionalDecoration.hxx
scilab/modules/ast/includes/analysis/TIType.hxx
scilab/modules/ast/includes/analysis/data/Block.hxx
scilab/modules/ast/includes/analysis/data/DataManager.hxx
scilab/modules/ast/includes/analysis/data/Info.hxx
scilab/modules/ast/includes/analysis/data/LoopBlock.hxx
scilab/modules/ast/includes/analysis/data/LoopDecoration.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/data/VarPromotion.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/gvn/ConstraintManager.hxx
scilab/modules/ast/includes/analysis/gvn/SymbolicDimension.hxx
scilab/modules/ast/includes/analysis/tools.hxx
scilab/modules/ast/src/cpp/analysis/AnalysisVisitor.cpp
scilab/modules/ast/src/cpp/analysis/Block.cpp
scilab/modules/ast/src/cpp/analysis/ConstraintManager.cpp
scilab/modules/ast/src/cpp/analysis/DataManager.cpp
scilab/modules/ast/src/cpp/analysis/DollarInfo.cpp [new file with mode: 0644]
scilab/modules/ast/src/cpp/analysis/FunctionBlock.cpp
scilab/modules/ast/src/cpp/analysis/IndexAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/Info.cpp
scilab/modules/ast/src/cpp/analysis/LoopBlock.cpp
scilab/modules/ast/src/cpp/analysis/MultivariateMonomial.cpp
scilab/modules/ast/src/cpp/analysis/MultivariatePolynomial.cpp
scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp
scilab/modules/ast/src/cpp/analysis/VisitDollarVar.cpp
scilab/modules/ast/src/cpp/analysis/VisitVarDec.cpp
scilab/modules/ast/src/cpp/analysis/VisitWhileExp.cpp [new file with mode: 0644]

index 19fd1e3..58ec79f 100644 (file)
@@ -142,6 +142,7 @@ src/cpp/analysis/PolymorphicMacroCache.cpp \
 src/cpp/analysis/SizeAnalyzer.cpp \
 src/cpp/analysis/SymbolicList.cpp \
 src/cpp/analysis/TIType.cpp \
+src/cpp/analysis/DollarInfo.cpp \
 src/cpp/analysis/IconvertAnalyzer.cpp \
 src/cpp/analysis/InttypeAnalyzer.cpp \
 src/cpp/analysis/IsrealAnalyzer.cpp \
@@ -159,6 +160,7 @@ src/cpp/analysis/VisitSelectExp.cpp \
 src/cpp/analysis/VisitAssignExp.cpp \
 src/cpp/analysis/VisitIfExp.cpp \
 src/cpp/analysis/VisitForExp.cpp \
+src/cpp/analysis/VisitWhileExp.cpp \
 src/cpp/analysis/VisitCallExp.cpp \
 src/cpp/analysis/VisitSeqExp.cpp \
 src/cpp/analysis/VisitTypeExps.cpp \
index ac797a6..6274268 100644 (file)
@@ -269,6 +269,7 @@ am__libsciast_la_SOURCES_DIST = src/c/operations/doublecomplex.c \
        src/cpp/analysis/PolymorphicMacroCache.cpp \
        src/cpp/analysis/SizeAnalyzer.cpp \
        src/cpp/analysis/SymbolicList.cpp src/cpp/analysis/TIType.cpp \
+       src/cpp/analysis/DollarInfo.cpp \
        src/cpp/analysis/IconvertAnalyzer.cpp \
        src/cpp/analysis/InttypeAnalyzer.cpp \
        src/cpp/analysis/IsrealAnalyzer.cpp \
@@ -285,6 +286,7 @@ am__libsciast_la_SOURCES_DIST = src/c/operations/doublecomplex.c \
        src/cpp/analysis/VisitAssignExp.cpp \
        src/cpp/analysis/VisitIfExp.cpp \
        src/cpp/analysis/VisitForExp.cpp \
+       src/cpp/analysis/VisitWhileExp.cpp \
        src/cpp/analysis/VisitCallExp.cpp \
        src/cpp/analysis/VisitSeqExp.cpp \
        src/cpp/analysis/VisitTypeExps.cpp \
@@ -496,6 +498,7 @@ am_libsciast_la_OBJECTS =  \
        src/cpp/analysis/libsciast_la-SizeAnalyzer.lo \
        src/cpp/analysis/libsciast_la-SymbolicList.lo \
        src/cpp/analysis/libsciast_la-TIType.lo \
+       src/cpp/analysis/libsciast_la-DollarInfo.lo \
        src/cpp/analysis/libsciast_la-IconvertAnalyzer.lo \
        src/cpp/analysis/libsciast_la-InttypeAnalyzer.lo \
        src/cpp/analysis/libsciast_la-IsrealAnalyzer.lo \
@@ -513,6 +516,7 @@ am_libsciast_la_OBJECTS =  \
        src/cpp/analysis/libsciast_la-VisitAssignExp.lo \
        src/cpp/analysis/libsciast_la-VisitIfExp.lo \
        src/cpp/analysis/libsciast_la-VisitForExp.lo \
+       src/cpp/analysis/libsciast_la-VisitWhileExp.lo \
        src/cpp/analysis/libsciast_la-VisitCallExp.lo \
        src/cpp/analysis/libsciast_la-VisitSeqExp.lo \
        src/cpp/analysis/libsciast_la-VisitTypeExps.lo \
@@ -973,6 +977,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -1078,6 +1083,7 @@ libsciast_la_SOURCES = src/c/operations/doublecomplex.c \
        src/cpp/analysis/PolymorphicMacroCache.cpp \
        src/cpp/analysis/SizeAnalyzer.cpp \
        src/cpp/analysis/SymbolicList.cpp src/cpp/analysis/TIType.cpp \
+       src/cpp/analysis/DollarInfo.cpp \
        src/cpp/analysis/IconvertAnalyzer.cpp \
        src/cpp/analysis/InttypeAnalyzer.cpp \
        src/cpp/analysis/IsrealAnalyzer.cpp \
@@ -1094,6 +1100,7 @@ libsciast_la_SOURCES = src/c/operations/doublecomplex.c \
        src/cpp/analysis/VisitAssignExp.cpp \
        src/cpp/analysis/VisitIfExp.cpp \
        src/cpp/analysis/VisitForExp.cpp \
+       src/cpp/analysis/VisitWhileExp.cpp \
        src/cpp/analysis/VisitCallExp.cpp \
        src/cpp/analysis/VisitSeqExp.cpp \
        src/cpp/analysis/VisitTypeExps.cpp \
@@ -1972,6 +1979,9 @@ src/cpp/analysis/libsciast_la-SymbolicList.lo:  \
 src/cpp/analysis/libsciast_la-TIType.lo:  \
        src/cpp/analysis/$(am__dirstamp) \
        src/cpp/analysis/$(DEPDIR)/$(am__dirstamp)
+src/cpp/analysis/libsciast_la-DollarInfo.lo:  \
+       src/cpp/analysis/$(am__dirstamp) \
+       src/cpp/analysis/$(DEPDIR)/$(am__dirstamp)
 src/cpp/analysis/libsciast_la-IconvertAnalyzer.lo:  \
        src/cpp/analysis/$(am__dirstamp) \
        src/cpp/analysis/$(DEPDIR)/$(am__dirstamp)
@@ -2023,6 +2033,9 @@ src/cpp/analysis/libsciast_la-VisitIfExp.lo:  \
 src/cpp/analysis/libsciast_la-VisitForExp.lo:  \
        src/cpp/analysis/$(am__dirstamp) \
        src/cpp/analysis/$(DEPDIR)/$(am__dirstamp)
+src/cpp/analysis/libsciast_la-VisitWhileExp.lo:  \
+       src/cpp/analysis/$(am__dirstamp) \
+       src/cpp/analysis/$(DEPDIR)/$(am__dirstamp)
 src/cpp/analysis/libsciast_la-VisitCallExp.lo:  \
        src/cpp/analysis/$(am__dirstamp) \
        src/cpp/analysis/$(DEPDIR)/$(am__dirstamp)
@@ -2338,6 +2351,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-Data.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-DataManager.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-DiagAnalyzer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-DollarInfo.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-FindAnalyzer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-FunctionBlock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-GVN.Plo@am__quote@
@@ -2381,6 +2395,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitSimpleVar.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitTypeExps.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitVarDec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitWhileExp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-XBlock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-check_____add____.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/analysis/$(DEPDIR)/libsciast_la-check_____and____.Plo@am__quote@
@@ -3495,6 +3510,13 @@ src/cpp/analysis/libsciast_la-TIType.lo: src/cpp/analysis/TIType.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/analysis/libsciast_la-TIType.lo `test -f 'src/cpp/analysis/TIType.cpp' || echo '$(srcdir)/'`src/cpp/analysis/TIType.cpp
 
+src/cpp/analysis/libsciast_la-DollarInfo.lo: src/cpp/analysis/DollarInfo.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/analysis/libsciast_la-DollarInfo.lo -MD -MP -MF src/cpp/analysis/$(DEPDIR)/libsciast_la-DollarInfo.Tpo -c -o src/cpp/analysis/libsciast_la-DollarInfo.lo `test -f 'src/cpp/analysis/DollarInfo.cpp' || echo '$(srcdir)/'`src/cpp/analysis/DollarInfo.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/analysis/$(DEPDIR)/libsciast_la-DollarInfo.Tpo src/cpp/analysis/$(DEPDIR)/libsciast_la-DollarInfo.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/analysis/DollarInfo.cpp' object='src/cpp/analysis/libsciast_la-DollarInfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/analysis/libsciast_la-DollarInfo.lo `test -f 'src/cpp/analysis/DollarInfo.cpp' || echo '$(srcdir)/'`src/cpp/analysis/DollarInfo.cpp
+
 src/cpp/analysis/libsciast_la-IconvertAnalyzer.lo: src/cpp/analysis/IconvertAnalyzer.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/analysis/libsciast_la-IconvertAnalyzer.lo -MD -MP -MF src/cpp/analysis/$(DEPDIR)/libsciast_la-IconvertAnalyzer.Tpo -c -o src/cpp/analysis/libsciast_la-IconvertAnalyzer.lo `test -f 'src/cpp/analysis/IconvertAnalyzer.cpp' || echo '$(srcdir)/'`src/cpp/analysis/IconvertAnalyzer.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/analysis/$(DEPDIR)/libsciast_la-IconvertAnalyzer.Tpo src/cpp/analysis/$(DEPDIR)/libsciast_la-IconvertAnalyzer.Plo
@@ -3614,6 +3636,13 @@ src/cpp/analysis/libsciast_la-VisitForExp.lo: src/cpp/analysis/VisitForExp.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/analysis/libsciast_la-VisitForExp.lo `test -f 'src/cpp/analysis/VisitForExp.cpp' || echo '$(srcdir)/'`src/cpp/analysis/VisitForExp.cpp
 
+src/cpp/analysis/libsciast_la-VisitWhileExp.lo: src/cpp/analysis/VisitWhileExp.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/analysis/libsciast_la-VisitWhileExp.lo -MD -MP -MF src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitWhileExp.Tpo -c -o src/cpp/analysis/libsciast_la-VisitWhileExp.lo `test -f 'src/cpp/analysis/VisitWhileExp.cpp' || echo '$(srcdir)/'`src/cpp/analysis/VisitWhileExp.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitWhileExp.Tpo src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitWhileExp.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/analysis/VisitWhileExp.cpp' object='src/cpp/analysis/libsciast_la-VisitWhileExp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/analysis/libsciast_la-VisitWhileExp.lo `test -f 'src/cpp/analysis/VisitWhileExp.cpp' || echo '$(srcdir)/'`src/cpp/analysis/VisitWhileExp.cpp
+
 src/cpp/analysis/libsciast_la-VisitCallExp.lo: src/cpp/analysis/VisitCallExp.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/analysis/libsciast_la-VisitCallExp.lo -MD -MP -MF src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitCallExp.Tpo -c -o src/cpp/analysis/libsciast_la-VisitCallExp.lo `test -f 'src/cpp/analysis/VisitCallExp.cpp' || echo '$(srcdir)/'`src/cpp/analysis/VisitCallExp.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitCallExp.Tpo src/cpp/analysis/$(DEPDIR)/libsciast_la-VisitCallExp.Plo
index 419a559..00792c2 100644 (file)
@@ -297,6 +297,7 @@ lib /DEF:"$(ProjectDir)coverage_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platfo
     <ClInclude Include="includes\analysis\data\Info.hxx" />
     <ClInclude Include="includes\analysis\data\LoopAnalyzer.hxx" />
     <ClInclude Include="includes\analysis\data\LoopBlock.hxx" />
+    <ClInclude Include="includes\analysis\data\LoopDecoration.hxx" />
     <ClInclude Include="includes\analysis\data\MacroDef.hxx" />
     <ClInclude Include="includes\analysis\data\MacroSignature.hxx" />
     <ClInclude Include="includes\analysis\data\PolymorphicMacroCache.hxx" />
@@ -304,6 +305,7 @@ lib /DEF:"$(ProjectDir)coverage_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platfo
     <ClInclude Include="includes\analysis\data\TITypeSignatureTuple.hxx" />
     <ClInclude Include="includes\analysis\data\TITypeTuple.hxx" />
     <ClInclude Include="includes\analysis\data\TypeLocal.hxx" />
+    <ClInclude Include="includes\analysis\data\VarPromotion.hxx" />
     <ClInclude Include="includes\analysis\data\XBlock.hxx" />
     <ClInclude Include="includes\analysis\Decorator.hxx" />
     <ClInclude Include="includes\analysis\DollarInfo.hxx" />
@@ -602,6 +604,7 @@ lib /DEF:"$(ProjectDir)coverage_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platfo
     <ClCompile Include="src\cpp\analysis\Data.cpp" />
     <ClCompile Include="src\cpp\analysis\DataManager.cpp" />
     <ClCompile Include="src\cpp\analysis\DiagAnalyzer.cpp" />
+    <ClCompile Include="src\cpp\analysis\DollarInfo.cpp" />
     <ClCompile Include="src\cpp\analysis\FindAnalyzer.cpp" />
     <ClCompile Include="src\cpp\analysis\FunctionBlock.cpp" />
     <ClCompile Include="src\cpp\analysis\GlobalsCollector.cpp" />
@@ -645,6 +648,7 @@ lib /DEF:"$(ProjectDir)coverage_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platfo
     <ClCompile Include="src\cpp\analysis\VisitSimpleVar.cpp" />
     <ClCompile Include="src\cpp\analysis\VisitTypeExps.cpp" />
     <ClCompile Include="src\cpp\analysis\VisitVarDec.cpp" />
+    <ClCompile Include="src\cpp\analysis\VisitWhileExp.cpp" />
     <ClCompile Include="src\cpp\analysis\XBlock.cpp" />
     <ClCompile Include="src\cpp\ast\consoledebugger.cpp" />
     <ClCompile Include="src\cpp\ast\debuggervisitor.cpp" />
index 811a7a0..18c49b3 100644 (file)
     <ClInclude Include="includes\types\addfunction.h">
       <Filter>Header Files\types</Filter>
     </ClInclude>
+    <ClInclude Include="includes\analysis\data\LoopDecoration.hxx">
+      <Filter>Header Files\analysis\data</Filter>
+    </ClInclude>
+    <ClInclude Include="includes\analysis\data\VarPromotion.hxx">
+      <Filter>Header Files\analysis\data</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\cpp\ast\expHistory.cpp">
     <ClCompile Include="src\cpp\system_env\coverage_instance.cpp">
       <Filter>Source Files\ast</Filter>
     </ClCompile>
+    <ClCompile Include="src\cpp\analysis\DollarInfo.cpp">
+      <Filter>Source Files\analysis</Filter>
+    </ClCompile>
+    <ClCompile Include="src\cpp\analysis\VisitWhileExp.cpp">
+      <Filter>Source Files\analysis</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
index 234cd06..95afd87 100644 (file)
@@ -365,6 +365,7 @@ private:
     void visit(ast::CommentExp & e) { }
     void visit(ast::NilExp & e) { }
     void visit(ast::ColonVar & e) { }
+    void visit(ast::WhileExp & e);
 
     void visit(ast::ArrayListVar & e)
     {
@@ -388,16 +389,6 @@ private:
         visit(static_cast<ast::OpExp &>(e));
     }
 
-    void visit(ast::WhileExp & e)
-    {
-        logger.log(L"WhileExp", e.getLocation());
-        loops.push(&e);
-        e.getTest().accept(*this);
-        dm.releaseTmp(getResult().getTempId(), &e.getTest());
-        e.getBody().accept(*this);
-        loops.pop();
-    }
-
     void visit(ast::BreakExp & e)
     {
         logger.log(L"BreakExp", e.getLocation());
index 4bc9d54..979fba9 100644 (file)
@@ -66,30 +66,45 @@ struct Decorator
         return *call;
     }
 
-    inline Clone * getClone() const
+    inline LoopDecoration * getLoopDecoration() const
     {
-        return opt.get<Clone>();
+        return opt.get<LoopDecoration>();
     }
 
-    inline Clone & setClone(Clone * _clone)
+    inline LoopDecoration & setLoopDecoration(LoopDecoration * _ld)
     {
-        opt.set(_clone);
-        return *_clone;
+        opt.set(_ld);
+        return *_ld;
     }
 
-    inline Clone & addClone(const symbol::Symbol & sym)
+    inline void addClone(const symbol::Symbol & sym)
     {
-        Clone * clone = opt.get<Clone>();
-        if (clone)
+        LoopDecoration * ld = opt.get<LoopDecoration>();
+        if (ld)
         {
-            clone->add(sym);
+            ld->addClone(sym);
         }
         else
         {
-            clone = new Clone(sym);
-            opt.set(clone);
+            ld = new LoopDecoration();
+            ld->addClone(sym);
+            opt.set(ld);
+        }
+    }
+
+    inline void addPromotion(const symbol::Symbol & sym, const TIType & first, const TIType & second)
+    {
+        LoopDecoration * ld = opt.get<LoopDecoration>();
+        if (ld)
+        {
+            ld->addPromotion(sym, first, second);
+        }
+        else
+        {
+            ld = new LoopDecoration();
+            ld->addPromotion(sym, first, second);
+            opt.set(ld);
         }
-        return *clone;
     }
 
     inline DollarInfo & setDollarInfo(const DollarInfo & di)
index 02cfef3..d83971c 100644 (file)
 #define __DOLLAR_INFO_HXX__
 
 #include <iostream>
-#include "symbol.hxx"
 #include <cstdint>
 
+namespace ast
+{
+class SimpleVar;
+}
+
 namespace analysis
 {
 
 class DollarInfo
 {
 
-    const symbol::Symbol sym;
+    const ast::SimpleVar & var;
+    const uint32_t argsCount;
     uint32_t index;
 
 public:
 
-    DollarInfo(const symbol::Symbol _sym, const uint32_t _index) : sym(_sym), index(_index) { }
+    DollarInfo(const ast::SimpleVar & _var, const uint32_t _argsCount, const uint32_t _index) : var(_var), argsCount(_argsCount), index(_index) { }
 
-    inline symbol::Symbol getSymbol() const
+    inline const ast::SimpleVar & getVar() const
     {
-        return sym;
+        return var;
+    }
+
+    inline uint32_t getArgsCount() const
+    {
+        return argsCount;
     }
 
     inline uint32_t getIndex() const
@@ -45,11 +55,7 @@ public:
         return index;
     }
 
-    friend std::wostream & operator<<(std::wostream & out, const DollarInfo & di)
-    {
-        out << L"$ in " << di.sym << L" at index " << di.index;
-        return out;
-    }
+    friend std::wostream & operator<<(std::wostream & out, const DollarInfo & di);
 
 };
 
index 0cf8069..9bccd53 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "call/Call.hxx"
 #include "data/Clone.hxx"
+#include "data/LoopDecoration.hxx"
 #include "DollarInfo.hxx"
 
 namespace analysis
@@ -24,7 +25,7 @@ namespace analysis
 
 class OptionalDecoration
 {
-    enum Type { NONE, CALL, CLONE, DOLLAR };
+    enum Type { NONE, CALL, LOOP, DOLLAR };
 
     Type ty;
     void * ptr;
@@ -33,7 +34,7 @@ public:
 
     OptionalDecoration() : ty(NONE), ptr(nullptr) { }
     OptionalDecoration(Call * _ptr) : ty(CALL), ptr(_ptr) { }
-    OptionalDecoration(Clone * _ptr) : ty(CLONE), ptr(_ptr) { }
+    OptionalDecoration(LoopDecoration * _ptr) : ty(LOOP), ptr(_ptr) { }
     OptionalDecoration(DollarInfo * _ptr) : ty(DOLLAR), ptr(_ptr) { }
     OptionalDecoration(OptionalDecoration && od) : ty(od.ty), ptr(od.ptr)
     {
@@ -66,10 +67,10 @@ public:
         ptr = _ptr;
     }
 
-    inline void set(Clone * _ptr)
+    inline void set(LoopDecoration * _ptr)
     {
         clean();
-        ty = CLONE;
+        ty = LOOP;
         ptr = _ptr;
     }
 
@@ -87,8 +88,8 @@ public:
             case CALL:
                 out << *od.get<Call>();
                 break;
-            case CLONE:
-                out << *od.get<Clone>();
+            case LOOP:
+                out << *od.get<LoopDecoration>();
                 break;
             case DOLLAR:
                 out << *od.get<DollarInfo>();
@@ -109,8 +110,8 @@ private:
             case CALL:
                 delete get<Call>();
                 break;
-            case CLONE:
-                delete get<Clone>();
+            case LOOP:
+                delete get<LoopDecoration>();
                 break;
             case DOLLAR:
                 delete get<DollarInfo>();
index 27cc94b..1f05b2a 100644 (file)
@@ -238,6 +238,66 @@ struct TIType
         }
     }
 
+    inline std::wstring get_manglingW() const
+    {
+        const bool kd = isKnownDims();
+        switch (type)
+        {
+            case EMPTY :
+                return L"E";
+            case BOOLEAN :
+                return kd ? (scalar ? L"Sb" : L"Mb") : L"Ub";
+            case COMPLEX :
+                return kd ? (scalar ? L"Sc" : L"Mc") : L"Uc";
+            case CELL :
+                return kd ? (scalar ? L"Sce" : L"Mce") : L"Uce";
+            case DOUBLE :
+                return kd ? (scalar ? L"Sd" : L"Md") : L"Ud";
+            case FUNCTION :
+                return kd ? (scalar ? L"Sfn" : L"Mfn") : L"Ufn";
+            case INT16 :
+                return kd ? (scalar ? L"Si16" : L"Mi16") : L"Ui16";
+            case INT32 :
+                return kd ? (scalar ? L"Si32" : L"Mi32") : L"Ui32";
+            case INT64 :
+                return kd ? (scalar ? L"Si64" : L"Mi64") : L"Ui64";
+            case INT8 :
+                return kd ? (scalar ? L"Si8" : L"Mi8") : L"Ui8";
+            case LIST :
+                return kd ? (scalar ? L"Sl" : L"Ml") : L"Ul";
+            case LIBRARY :
+                return kd ? (scalar ? L"Slb" : L"Mlb") : L"Ulb";
+            case MACRO :
+                return kd ? (scalar ? L"Sm" : L"Mm") : L"Um";
+            case MACROFILE :
+                return kd ? (scalar ? L"Smf" : L"Mmf") : L"Umf";
+            case MLIST :
+                return kd ? (scalar ? L"Sml" : L"Mml") : L"Uml";
+            case POLYNOMIAL :
+                return kd ? (scalar ? L"Sp" : L"Mp") : L"Up";
+            case STRING :
+                return kd ? (scalar ? L"Ss" : L"Ms") : L"Us";
+            case SPARSE :
+                return kd ? (scalar ? L"Ssp" : L"Msp") : L"Usp";
+            case STRUCT :
+                return kd ? (scalar ? L"Sst" : L"Mst") : L"Ust";
+            case TLIST :
+                return kd ? (scalar ? L"Stl" : L"Mtl") : L"Utl";
+            case UNKNOWN :
+                return kd ? (scalar ? L"Su" : L"Mu") : L"Uu";
+            case UINT16 :
+                return kd ? (scalar ? L"Sui16" : L"Mui16") : L"Uui16";
+            case UINT32 :
+                return kd ? (scalar ? L"Sui32" : L"Mui32") : L"Uui32";
+            case UINT64 :
+                return kd ? (scalar ? L"Sui64" : L"Mui64") : L"Uui64";
+            case UINT8 :
+                return kd ? (scalar ? L"Sui8" : L"Mui8") : L"Uui8";
+            default :
+                return L"??";
+        }
+    }
+
     inline static std::string get_mangling(const TIType::Type ty, const bool scalar)
     {
         switch (ty)
@@ -297,11 +357,75 @@ struct TIType
         }
     }
 
+    inline static std::wstring get_manglingW(const TIType::Type ty, const bool scalar)
+    {
+        switch (ty)
+        {
+            case EMPTY :
+                return L"E";
+            case BOOLEAN :
+                return scalar ? L"Sb" : L"Mb";
+            case COMPLEX :
+                return scalar ? L"Sc" : L"Mc";
+            case CELL :
+                return scalar ? L"Sce" : L"Mce";
+            case DOUBLE :
+                return scalar ? L"Sd" : L"Md";
+            case FUNCTION :
+                return scalar ? L"Sfn" : L"Mfn";
+            case INT16 :
+                return scalar ? L"Si16" : L"Mi16";
+            case INT32 :
+                return scalar ? L"Si32" : L"Mi32";
+            case INT64 :
+                return scalar ? L"Si64" : L"Mi64";
+            case INT8 :
+                return scalar ? L"Si8" : L"Mi8";
+            case LIST :
+                return scalar ? L"Sl" : L"Ml";
+            case LIBRARY :
+                return scalar ? L"Slb" : L"Mlb";
+            case MACRO :
+                return scalar ? L"Sm" : L"Mm";
+            case MACROFILE :
+                return scalar ? L"Smf" : L"Mmf";
+            case MLIST :
+                return scalar ? L"Sml" : L"Mml";
+            case POLYNOMIAL :
+                return scalar ? L"Sp" : L"Mp";
+            case STRING :
+                return scalar ? L"Ss" : L"Ms";
+            case SPARSE :
+                return scalar ? L"Ssp" : L"Msp";
+            case STRUCT :
+                return scalar ? L"Sst" : L"Mst";
+            case TLIST :
+                return scalar ? L"Stl" : L"Mtl";
+            case UNKNOWN :
+                return scalar ? L"Su" : L"Mu";
+            case UINT16 :
+                return scalar ? L"Sui16" : L"Mui16";
+            case UINT32 :
+                return scalar ? L"Sui32" : L"Mui32";
+            case UINT64 :
+                return scalar ? L"Sui64" : L"Mui64";
+            case UINT8 :
+                return scalar ? L"Sui8" : L"Mui8";
+            default :
+                return L"??";
+        }
+    }
+
     inline static std::string get_unary_mangling(const std::string & pre, const TIType & l)
     {
         return pre + "_" + l.get_mangling();
     }
 
+    inline static std::wstring get_unary_manglingW(const std::wstring & pre, const TIType & l)
+    {
+        return pre + L"_" + l.get_manglingW();
+    }
+
     inline static std::string get_binary_mangling(const std::string & pre, const TIType & l, const TIType & r)
     {
         return pre + "_" + l.get_mangling() + r.get_mangling();
@@ -691,4 +815,4 @@ struct hash<analysis::TIType>
 };
 } // namespace std
 
-#endif // __TITYPE_HXX__
\ No newline at end of file
+#endif // __TITYPE_HXX__
index 7e88fac..cdf0e42 100644 (file)
@@ -117,7 +117,7 @@ public:
     virtual Info & addRead(const symbol::Symbol & sym, ast::Exp * exp);
     virtual Info & addWrite(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp);
     virtual Info & addDefine(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp);
-    virtual Info & addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp);
+    virtual Info & addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp);
     virtual Info & addMacroDef(ast::FunctionDec * dec);
     virtual std::vector<TIType> addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId);
     virtual Info & addClear(const symbol::Symbol & sym, ast::Exp * exp);
index 00cf8ac..4a0a352 100644 (file)
@@ -68,7 +68,7 @@ public:
     Info & read(const symbol::Symbol & sym, ast::Exp * exp);
     Info & write(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp);
     Info & define(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp);
-    Info & share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp);
+    Info & share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp);
     Info & clear(const symbol::Symbol & sym, ast::Exp * exp);
     Info & macrodef(ast::Exp * exp);
     std::vector<TIType> call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId);
index 0844034..f4abd0a 100644 (file)
@@ -65,6 +65,7 @@ struct Info
     const ConstantValue & getConstant() const;
     ConstantValue & setConstant(ConstantValue & val);
     bool isknown() const;
+    bool isAnInt() const;
     static const symbol::Symbol & getRightSym(ast::Exp * exp);
     const TIType & getType() const;
     friend std::wostream & operator<<(std::wostream & out, const Info & info);
index 2591070..6ec0c9e 100644 (file)
@@ -49,7 +49,10 @@ class LoopBlockHead : public Block
 
 public:
 
-    LoopBlockHead(const unsigned int id, Block * parent, ast::Exp * exp) : Block(id, parent, exp) { }
+    LoopBlockHead(const unsigned int id, Block * parent, ast::Exp * exp) : Block(id, parent, exp)
+    {
+        blocks.reserve(2);
+    }
 
     inline Block * getFirstBlock()
     {
@@ -74,6 +77,7 @@ class LoopBlock : public Block
     std::unordered_map<ast::Exp *, symbol::Symbol> clonedSym;
 
 public:
+
     LoopBlock(const unsigned int id, Block * parent, ast::Exp * exp, const bool _first) : Block(id, parent, exp), first(_first) { }
 
     inline LoopBlockHead * getParent()
diff --git a/scilab/modules/ast/includes/analysis/data/LoopDecoration.hxx b/scilab/modules/ast/includes/analysis/data/LoopDecoration.hxx
new file mode 100644 (file)
index 0000000..0a10caf
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#ifndef __LOOPDECORATION_HXX__
+#define __LOOPDECORATION_HXX__
+
+#include <iostream>
+
+#include "tools.hxx"
+#include "Clone.hxx"
+#include "VarPromotion.hxx"
+
+namespace analysis
+{
+
+class LoopDecoration
+{
+
+    Clone clone;
+    VarPromotion promotion;
+
+public:
+
+    LoopDecoration() { }
+
+    inline void addClone(const symbol::Symbol & sym)
+    {
+        clone.add(sym);
+    }
+
+    inline const tools::SymbolSet & getClone() const
+    {
+        return clone.get();
+    }
+
+    inline void addPromotion(const symbol::Symbol & sym, const TIType & first, const TIType & second)
+    {
+        promotion.add(sym, first, second);
+    }
+
+    inline const tools::SymbolMap<VarPromotion::Promotion> & getPromotion() const
+    {
+        return promotion.get();
+    }
+
+    inline void clear()
+    {
+        clone.clear();
+        promotion.clear();
+    }
+
+    friend std::wostream & operator<<(std::wostream & out, const LoopDecoration & ld)
+    {
+        const bool cl = ld.getClone().empty();
+        const bool pr = ld.getPromotion().empty();
+
+        if (!cl || !pr)
+        {
+            out << L"LoopDecoration: ";
+            if (!cl)
+            {
+                out << ld.clone;
+                if (pr)
+                {
+                    out << L"; ";
+                }
+            }
+            if (!pr)
+            {
+                out << ld.promotion;
+            }
+        }
+
+        return out;
+    }
+};
+
+} // namespace analysis
+
+
+#endif // __LOOPDECORATION_HXX__
diff --git a/scilab/modules/ast/includes/analysis/data/VarPromotion.hxx b/scilab/modules/ast/includes/analysis/data/VarPromotion.hxx
new file mode 100644 (file)
index 0000000..944ea27
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#ifndef __VARPROMOTION_HXX__
+#define __VARPROMOTION_HXX__
+
+#include <iostream>
+
+#include "tools.hxx"
+#include "TIType.hxx"
+
+namespace analysis
+{
+
+class VarPromotion
+{
+
+public:
+
+    struct Promotion
+    {
+        TIType first;
+        TIType second;
+
+        Promotion(const TIType & _first, const TIType & _second) : first(_first), second(_second) { }
+
+        friend std::wostream & operator<<(std::wostream & out, const Promotion & p)
+        {
+            out << L"(" << p.first << L" => " << p.second << L")";
+            return out;
+        }
+    };
+
+private:
+
+    tools::SymbolMap<Promotion> map;
+
+public:
+
+    VarPromotion() { }
+
+    inline void add(const symbol::Symbol & sym, const TIType & first, const TIType & second)
+    {
+        map.emplace(sym, Promotion(first, second));
+    }
+
+    inline const tools::SymbolMap<Promotion> & get() const
+    {
+        return map;
+    }
+
+    inline void clear()
+    {
+        map.clear();
+    }
+
+    friend std::wostream & operator<<(std::wostream & out, const VarPromotion & c)
+    {
+        out << L"VarPromotion";
+        tools::printMap(c.map, out);
+
+        return out;
+    }
+};
+
+} // namespace analysis
+
+
+#endif // __VARPROMOTION_HXX__
index e887277..a5d0efe 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef __CONSTRAINT_MANAGER_HXX__
 #define __CONSTRAINT_MANAGER_HXX__
 
+#include <iostream>
 #include <memory>
 #include <string>
 #include <set>
 namespace analysis
 {
 
-    class FunctionBlock;
+class FunctionBlock;
 
-    class EXTERN_AST ConstraintManager
+class EXTERN_AST ConstraintManager
+{
+
+public:
+
+    typedef std::unordered_set<MPolyConstraintSet, MPolyConstraintSet::Hash, MPolyConstraintSet::Eq> UnverifiedSet;
+
+private:
+
+    ConstraintManager * parent;
+    FunctionBlock * function;
+    MPolyConstraintSet verified;
+    std::set<symbol::Symbol> constantConstraints;
+    UnverifiedSet unverified;
+
+    static std::vector<std::shared_ptr<InferenceConstraint>> generalConstraints;
+
+public:
+
+    enum Kind { SAMEDIMS = 0, EQUAL, POSITIVE, STRICT_POSITIVE, GREATER, STRICT_GREATER, VALID_INDEX, VALID_RANGE, COUNT };
+
+    ConstraintManager(FunctionBlock * _function, FunctionBlock * _parent = nullptr);
+    ConstraintManager(FunctionBlock & _function, FunctionBlock * _parent = nullptr) : ConstraintManager(&_function, _parent) { }
+    ConstraintManager() : ConstraintManager(nullptr, nullptr) { }
+
+    inline bool isRoot() const
+    {
+        return parent == nullptr;
+    }
+
+    inline const MPolyConstraintSet & getVerifiedConstraints() const
     {
+        return verified;
+    }
+
+    inline const UnverifiedSet & getUnverifiedConstraints() const
+    {
+        return unverified;
+    }
+
+    inline const std::set<symbol::Symbol> & getGlobalConstants() const
+    {
+        return constantConstraints;
+    }
+
+    bool check(const MPolyConstraintSet & set, const std::vector<GVN::Value *> & values);
+    bool check(Kind kind, const std::vector<GVN::Value *> & values);
+    bool checkGlobalConstant(const symbol::Symbol & sym);
+
+    friend std::wostream & operator<<(std::wostream & out, const ConstraintManager & cm);
+
+    static bool checkGlobalConstants(const std::set<symbol::Symbol> & gc);
+
+    template<typename... Args>
+    inline bool check(Kind kind, Args... args)
+    {
+        std::vector<GVN::Value *> v;
+        return __check(kind, v, args...);
+    }
+
+private:
+
+    inline bool __check(Kind kind, const std::vector<GVN::Value *> & v)
+    {
+        return check(kind, v);
+    }
+
+    template<typename... Args>
+    inline bool __check(Kind kind, std::vector<GVN::Value *> & v, GVN::Value & val, Args... args)
+    {
+        v.emplace_back(&val);
+        return __check(kind, v, args...);
+    }
+
+    template<typename... Args>
+    inline bool __check(Kind kind, std::vector<GVN::Value *> & v, GVN::Value * val, Args... args)
+    {
+        v.emplace_back(val);
+        return __check(kind, v, args...);
+    }
+
+    static std::vector<std::shared_ptr<InferenceConstraint>> init();
 
-    public:
-
-       typedef std::unordered_set<MPolyConstraintSet, MPolyConstraintSet::Hash, MPolyConstraintSet::Eq> UnverifiedSet;
-
-    private:
-       
-        ConstraintManager * parent;
-        FunctionBlock * function;
-        MPolyConstraintSet verified;
-       std::set<symbol::Symbol> constantConstraints;
-       UnverifiedSet unverified;
-       
-        static std::vector<std::shared_ptr<InferenceConstraint>> generalConstraints;
-
-    public:
-
-        enum Kind { SAMEDIMS = 0, EQUAL, POSITIVE, STRICT_POSITIVE, GREATER, STRICT_GREATER, VALID_INDEX, VALID_RANGE, COUNT };
-
-        ConstraintManager(FunctionBlock * _function, FunctionBlock * _parent = nullptr);
-        ConstraintManager(FunctionBlock & _function, FunctionBlock * _parent = nullptr) : ConstraintManager(&_function, _parent) { }
-        ConstraintManager() : ConstraintManager(nullptr, nullptr) { }
-
-        inline bool isRoot() const
-        {
-            return parent == nullptr;
-        }
-
-        inline const MPolyConstraintSet & getVerifiedConstraints() const
-        {
-            return verified;
-        }
-
-       inline const UnverifiedSet & getUnverifiedConstraints() const
-        {
-            return unverified;
-       }
-
-       inline const std::set<symbol::Symbol> & getGlobalConstants() const
-       {
-            return constantConstraints;
-        }
-
-        bool check(const MPolyConstraintSet & set, const std::vector<GVN::Value *> & values);
-        bool check(Kind kind, const std::vector<GVN::Value *> & values);
-       bool checkGlobalConstant(const symbol::Symbol & sym);
-
-       static bool checkGlobalConstants(const std::set<symbol::Symbol> & gc);
-       
-        template<typename... Args>
-       inline bool check(Kind kind, Args... args)
-        {
-            std::vector<GVN::Value *> v;
-            return __check(kind, v, args...);
-        }
-
-    private:
-
-        inline bool __check(Kind kind, const std::vector<GVN::Value *> & v)
-        {
-            return check(kind, v);
-        }
-
-        template<typename... Args>
-        inline bool __check(Kind kind, std::vector<GVN::Value *> & v, GVN::Value & val, Args... args)
-        {
-            v.emplace_back(&val);
-            return __check(kind, v, args...);
-        }
-
-        template<typename... Args>
-        inline bool __check(Kind kind, std::vector<GVN::Value *> & v, GVN::Value * val, Args... args)
-        {
-            v.emplace_back(val);
-            return __check(kind, v, args...);
-        }
-
-        static std::vector<std::shared_ptr<InferenceConstraint>> init();
-
-    };
+};
 
 } // namespace analysis
 
index 2effa11..4d217b7 100644 (file)
@@ -78,10 +78,10 @@ public:
      * \return true if empty
      */
     inline bool empty() const
-       {
-           return gvn == nullptr || value == nullptr;
-       }
-    
+    {
+        return gvn == nullptr || value == nullptr;
+    }
+
     /**
      * \brief Check if this dimension is valid
      * \return true if valid
@@ -168,30 +168,30 @@ public:
      * \param dim a dim
      */
     inline void mergeAsMax(const SymbolicDimension & dim)
-       {
-           bool mustInvalidate = true;
-           if (isValid() && dim.isValid())
-           {
-               if (value->poly && dim.value->poly)
-               {
-                   MultivariatePolynomial mp = *value->poly - *dim.value->poly;
-                   if (mp.isCoeffPositive())
-                   {
-                       value = dim.value;
-                       mustInvalidate = false;
-                   }
-                   else if (mp.isCoeffNegative())
-                   {
-                       mustInvalidate = false;
-                   }
-               }
-           }
-           if (mustInvalidate && gvn)
-           {
-               gvn = nullptr;
-               value = nullptr;
-           }
-       }
+    {
+        bool mustInvalidate = true;
+        if (isValid() && dim.isValid())
+        {
+            if (value->poly && dim.value->poly)
+            {
+                MultivariatePolynomial mp = *value->poly - *dim.value->poly;
+                if (mp.isCoeffPositive())
+                {
+                    value = dim.value;
+                    mustInvalidate = false;
+                }
+                else if (mp.isCoeffNegative())
+                {
+                    mustInvalidate = false;
+                }
+            }
+        }
+        if (mustInvalidate && gvn)
+        {
+            gvn = nullptr;
+            value = nullptr;
+        }
+    }
 
     /**
      * \brief Overload of the + operator
@@ -246,15 +246,19 @@ public:
      */
     inline SymbolicDimension & operator*=(const SymbolicDimension & R)
     {
-       if (R != 1)
-       {
-           if (*this != 1)
-           {
-               value = gvn->getValue(OpValue::Kind::TIMES, *value, *R.value);
-           }
-       }
-
-       return *this;
+        if (R != 1)
+        {
+            if (*this != 1)
+            {
+                value = gvn->getValue(OpValue::Kind::TIMES, *value, *R.value);
+            }
+            else
+            {
+                value = R.value;
+            }
+        }
+
+        return *this;
     }
 
     /**
index b996c2b..418c86a 100644 (file)
@@ -203,10 +203,10 @@ inline std::wostream & operator<<(std::wostream & out, const IntType & it)
             out << L"NAI";
             break;
         case IntType::SIGNED :
-            out << L"S";
+            out << L'S';
             break;
         case IntType::UNSIGNED :
-            out << L"U";
+            out << L'U';
             break;
     }
     return out;
@@ -237,16 +237,16 @@ static void printSet(const T & set, std::wostream & out)
     }
     else
     {
-        out << L"{";
+        out << L'{';
         for (typename T::const_iterator i = set.begin(); i != set.end(); ++i)
         {
             if (std::next(i) == set.end())
             {
-                out << *i << L"}";
+                out << *i << L'}';
             }
             else
             {
-                out << *i << L",";
+                out << *i << L',';
             }
         }
     }
@@ -261,20 +261,20 @@ static void printMap(const T & map, std::wostream & out, const bool newLine = fa
     }
     else
     {
-        out << L"{";
+        out << L'{';
         for (typename T::const_iterator i = map.begin(); i != map.end(); ++i)
         {
             out << i->first << L" -> " << i->second;
             if (std::next(i) == map.end())
             {
-                out << L"}";
+                out << L'}';
             }
             else
             {
-                out << L",";
+                out << L',';
                 if (newLine)
                 {
-                    out << L"\n";
+                    out << L'\n';
                 }
             }
         }
@@ -286,18 +286,18 @@ static void printMapInfo(std::wostream & out, const T & map, const bool show_col
 {
     double mean = 0;
     double variance = 0;
-    double count = map.bucket_count();
+    const unsigned int count = map.bucket_count();
     unsigned int empty_bucket_count = 0;
     unsigned int collision_count = 0;
 
     out << L"Map size: " << map.size() << std::endl;
     out << L"Number of buckets: " << count << std::endl;
 
-    for (unsigned int i = 0; i < map.bucket_count(); ++i)
+    for (unsigned int i = 0; i < count; ++i)
     {
-        if (unsigned int s = map.bucket_size(i))
+        if (const unsigned int s = map.bucket_size(i))
         {
-            mean += s;
+            mean += (double)s;
             if (s > 1)
             {
                 ++collision_count;
@@ -308,14 +308,14 @@ static void printMapInfo(std::wostream & out, const T & map, const bool show_col
             ++empty_bucket_count;
         }
     }
-    mean /= count;
+    mean /= (double)count;
 
-    for (unsigned int i = 0; i < map.bucket_count(); ++i)
+    for (unsigned int i = 0; i < count; ++i)
     {
-        const unsigned int s = map.bucket_size(i);
-        variance += (mean - s) * (mean - s);
+        const double ms = mean - (double)map.bucket_size(i);
+        variance += ms * ms;
     }
-    variance /= count;
+    variance /= (double)count;
 
     out << L"Number of elements by buckets: mean=" << mean << L", sigma=" << std::sqrt(variance) << std::endl;
     out << L"Number of empty buckets: " << empty_bucket_count << std::endl;
index d7c51d9..781f8e4 100644 (file)
@@ -279,8 +279,9 @@ void AnalysisVisitor::visitArguments(const std::wstring & name, const unsigned i
     vargs.reserve(args.size());
     resargs.reserve(args.size());
 
-    const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
-    argIndices.emplace(sym, 0);
+    const ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getName());
+    const symbol::Symbol & sym = var.getSymbol();
+    argIndices.emplace(var, args.size(), 0);
 
     for (auto arg : args)
     {
index 9c6c9a6..8730167 100644 (file)
@@ -251,15 +251,18 @@ Info & Block::addDefine(const symbol::Symbol & sym, const TIType & Rtype, const
     return info;
 }
 
-Info & Block::addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
+Info & Block::addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, const bool isIntIterator, ast::Exp * exp)
 {
-    addLocal(Lsym, Rtype, /* isIntIterator */ false);
+    addLocal(Lsym, Rtype, isIntIterator);
     Info & Linfo = putAndClear(Lsym, exp);
     Info & Rinfo = putSymsInScope(Rsym);
     Linfo.cleared = false;
     Linfo.type = Rtype;
     Linfo.data = Rinfo.data;
     Linfo.isint = Rinfo.isint;
+    Linfo.constant = Rinfo.constant;
+    Linfo.range = Rinfo.range;
+    Linfo.maxIndex = Rinfo.maxIndex;
     Linfo.data->add(Lsym);
     Linfo.exists = true;
 
@@ -280,7 +283,7 @@ Info & Block::addMacroDef(ast::FunctionDec * dec)
     return i;
 }
 
-    std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId)
+std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId)
 {
     tools::SymbolMap<Info>::iterator it;
     Block * block = getDefBlock(sym, it, false);
index 051eaa3..c29ff73 100644 (file)
@@ -55,36 +55,36 @@ bool ConstraintManager::check(const MPolyConstraintSet & set, const std::vector<
     {
         case InferenceConstraint::RESULT_TRUE:
         {
-           if (!set.empty())
-           {
-               verified.add(set);
-               set.applyConstraints(values);
-           }
+            if (!set.empty())
+            {
+                verified.add(set);
+                set.applyConstraints(values);
+            }
             return true;
         }
         case InferenceConstraint::RESULT_FALSE:
-           if (!set.empty())
-           {
-               unverified.emplace(set);
-           }
+            if (!set.empty())
+            {
+                unverified.emplace(set);
+            }
             return false;
         case InferenceConstraint::RESULT_DUNNO:
         {
             if (parent && parent->function)
             {
                 const bool ret = parent->check(set.getMPConstraints(values), parent->function->getInValues());
-               if (!set.empty())
-               {
-                   if (ret)
-                   {
-                       verified.add(set);
-                       set.applyConstraints(values);
-                   }
-                   else
-                   {
-                       unverified.emplace(set);
-                   }
-               }
+                if (!set.empty())
+                {
+                    if (ret)
+                    {
+                        verified.add(set);
+                        set.applyConstraints(values);
+                    }
+                    else
+                    {
+                        unverified.emplace(set);
+                    }
+                }
                 return ret;
             }
             else
@@ -101,43 +101,43 @@ bool ConstraintManager::check(Kind kind, const std::vector<GVN::Value *> & value
     {
         const InferenceConstraint & ic = *generalConstraints[kind];
         InferenceConstraint::Result res = ic.check(function->getGVN(), values);
-       const MPolyConstraintSet set = ic.getMPConstraints(values); 
+        const MPolyConstraintSet set = ic.getMPConstraints(values);
         //std::wcerr << "DEBUG2=" << res << std::endl;
 
         switch (res)
         {
             case InferenceConstraint::RESULT_TRUE:
             {
-               if (!set.empty())
-               {
-                   verified.add(set);
-                   ic.applyConstraints(values);
-               }
+                if (!set.empty())
+                {
+                    verified.add(set);
+                    ic.applyConstraints(values);
+                }
                 return true;
             }
             case InferenceConstraint::RESULT_FALSE:
-               if (!set.empty())
-               {
-                   unverified.emplace(set);
-               }
+                if (!set.empty())
+                {
+                    unverified.emplace(set);
+                }
                 return false;
             case InferenceConstraint::RESULT_DUNNO:
             {
                 MPolyConstraintSet set = ic.getMPConstraints(values);
                 const bool ret = check(set, function->getInValues());
 
-               if (!set.empty())
-               {
-                   if (ret)
-                   {
-                       verified.add(set);
-                       ic.applyConstraints(values);
-                   }
-                   else
-                   {
-                       unverified.emplace(set);
-                   }
-               }
+                if (!set.empty())
+                {
+                    if (ret)
+                    {
+                        verified.add(set);
+                        ic.applyConstraints(values);
+                    }
+                    else
+                    {
+                        unverified.emplace(set);
+                    }
+                }
                 return ret;
             }
         }
@@ -180,4 +180,28 @@ bool ConstraintManager::checkGlobalConstants(const std::set<symbol::Symbol> & gc
     }
     return true;
 }
+
+std::wostream & operator<<(std::wostream & out, const ConstraintManager & cm)
+{
+    if (!cm.verified.empty())
+    {
+        out << L"Verified: " << cm.verified << L'\n';
+    }
+    if (!cm.unverified.empty())
+    {
+        out << L"Unverified: ";
+        for (const auto & unv : cm.unverified)
+        {
+            out << unv << L' ';
+        }
+        out << L'\n';
+    }
+    if (!cm.constantConstraints.empty())
+    {
+        out << L"Constants: ";
+        tools::printSet(cm.constantConstraints, out);
+        out << L'\n';
+    }
+    return out;
+}
 }
index 02598da..8a4bb53 100644 (file)
 namespace analysis
 {
 
-    DataManager::DataManager() : id(0)
-    {
-        current = root = new Block(this);
-    }
+DataManager::DataManager() : id(0)
+{
+    current = root = new Block(this);
+}
 
-    DataManager::~DataManager()
+DataManager::~DataManager()
+{
+    for (const auto d : data)
     {
-        for (const auto d : data)
-        {
-            delete d;
-        }
-        delete root;
-        for (const auto & p : macroDefCache)
-        {
-            delete p.second;
-        }
+        delete d;
     }
-
-    void DataManager::reset()
+    delete root;
+    for (const auto & p : macroDefCache)
     {
-       for (const auto d : data)
-        {
-            delete d;
-        }
-       data.clear();
-       delete root;
-        current = root = new Block(this);
-       globals.clear();
-       while (!callStack.empty())
-       {
-           callStack.pop();
-       }
-       for (const auto & p : macroDefCache)
-        {
-            delete p.second;
-        }
-       macroDefCache.clear();
+        delete p.second;
     }
+}
 
-    GVN & DataManager::getGVN()
+void DataManager::reset()
+{
+    for (const auto d : data)
     {
-        return current->getGVN();
+        delete d;
     }
-
-    GVN & DataManager::getDefaultGVN()
+    data.clear();
+    delete root;
+    current = root = new Block(this);
+    globals.clear();
+    while (!callStack.empty())
     {
-        return gvn;
+        callStack.pop();
     }
-
-    MacroDef * DataManager::getMacroDef(types::Macro * macro)
+    for (const auto & p : macroDefCache)
     {
-        auto i = macroDefCache.find(macro);
-        if (i == macroDefCache.end())
-        {
-            i = macroDefCache.emplace(macro, new ExistingMacroDef(*macro)).first;
-        }
-        return i->second;
+        delete p.second;
     }
+    macroDefCache.clear();
+}
 
-    void DataManager::addGlobal(const symbol::Symbol & sym)
-    {
-        globals.emplace(sym);
-    }
+GVN & DataManager::getGVN()
+{
+    return current->getGVN();
+}
 
-    void DataManager::registerData(Data * _data, int line, char * file)
-    {
-        if (_data)
-        {
-            /*              bool ok = true;
-                            for (const auto d : data)
-                            {
-                            if (d == _data)
-                            {
-                            ok =  false;
-                            break;
-                            }
-                            }
-
-                            std::cout << "ptr added=" << _data << " line:" << line << " file:" << file << " doubloon:" << ok << std::endl;
-            */
-            data.push_back(_data);
-        }
-    }
+GVN & DataManager::getDefaultGVN()
+{
+    return gvn;
+}
 
-    int DataManager::getTmpId(const TIType & type, const bool isAnInt)
+MacroDef * DataManager::getMacroDef(types::Macro * macro)
+{
+    auto i = macroDefCache.find(macro);
+    if (i == macroDefCache.end())
     {
-        return current->getTmpId(type, isAnInt);
+        i = macroDefCache.emplace(macro, new ExistingMacroDef(*macro)).first;
     }
+    return i->second;
+}
 
-    void DataManager::releaseTmp(const int id, ast::Exp * exp)
-    {
-        current->releaseTmp(id, exp);
-    }
+void DataManager::addGlobal(const symbol::Symbol & sym)
+{
+    globals.emplace(sym);
+}
 
-    Info & DataManager::read(const symbol::Symbol & sym, ast::Exp * exp)
+void DataManager::registerData(Data * _data, int line, char * file)
+{
+    if (_data)
     {
-        return current->addRead(sym, exp);
+        /*              bool ok = true;
+                        for (const auto d : data)
+                        {
+                        if (d == _data)
+                        {
+                        ok =  false;
+                        break;
+                        }
+                        }
+
+                        std::cout << "ptr added=" << _data << " line:" << line << " file:" << file << " doubloon:" << ok << std::endl;
+        */
+        data.push_back(_data);
     }
+}
 
-    Info & DataManager::write(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
-    {
-        return current->addWrite(sym, Rtype, exp);
-    }
+int DataManager::getTmpId(const TIType & type, const bool isAnInt)
+{
+    return current->getTmpId(type, isAnInt);
+}
 
-    Info & DataManager::define(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp)
-    {
-        return current->addDefine(sym, Rtype, isAnInt, exp);
-    }
+void DataManager::releaseTmp(const int id, ast::Exp * exp)
+{
+    current->releaseTmp(id, exp);
+}
 
-    Info & DataManager::share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
-    {
-        return current->addShare(Lsym, Rsym, Rtype, exp);
-    }
+Info & DataManager::read(const symbol::Symbol & sym, ast::Exp * exp)
+{
+    return current->addRead(sym, exp);
+}
 
-    Info & DataManager::clear(const symbol::Symbol & sym, ast::Exp * exp)
-    {
-        return current->addClear(sym, exp);
-    }
+Info & DataManager::write(const symbol::Symbol & sym, const TIType & Rtype, ast::Exp * exp)
+{
+    return current->addWrite(sym, Rtype, exp);
+}
 
-    Info & DataManager::macrodef(ast::Exp * exp)
-    {
-        return current->addMacroDef(static_cast<ast::FunctionDec *>(exp));
-    }
+Info & DataManager::define(const symbol::Symbol & sym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp)
+{
+    return current->addDefine(sym, Rtype, isAnInt, exp);
+}
 
-    std::vector<TIType> DataManager::call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId)
-    {
-        return current->addCall(visitor, lhs, sym, in, callexp, functionId);
-    }
+Info & DataManager::share(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, const bool isAnInt, ast::Exp * exp)
+{
+    return current->addShare(Lsym, Rsym, Rtype, isAnInt, exp);
+}
 
-    void DataManager::addBlock(Block::BlockKind kind, ast::Exp * exp)
-    {
-        current = current->addBlock(++id, kind, exp);
-    }
+Info & DataManager::clear(const symbol::Symbol & sym, ast::Exp * exp)
+{
+    return current->addClear(sym, exp);
+}
 
-    Block * DataManager::getCurrent()
-    {
-        return current;
-    }
+Info & DataManager::macrodef(ast::Exp * exp)
+{
+    return current->addMacroDef(static_cast<ast::FunctionDec *>(exp));
+}
 
-    void DataManager::finalizeBlock()
-    {
+std::vector<TIType> DataManager::call(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp, uint64_t & functionId)
+{
+    return current->addCall(visitor, lhs, sym, in, callexp, functionId);
+}
+
+void DataManager::addBlock(Block::BlockKind kind, ast::Exp * exp)
+{
+    current = current->addBlock(++id, kind, exp);
+}
+
+Block * DataManager::getCurrent()
+{
+    return current;
+}
+
+void DataManager::finalizeBlock()
+{
 #ifndef DEBUG_DATAMANAGER
-        current->finalize();
+    current->finalize();
 #endif
-        current = current->parent;
-    }
+    current = current->parent;
+}
 
-    bool DataManager::requiresAnotherTrip()
-    {
-        return current->requiresAnotherTrip();
-    }
+bool DataManager::requiresAnotherTrip()
+{
+    return current->requiresAnotherTrip();
+}
 
-    void DataManager::pushFunction(FunctionBlock * fblock)
-    {
-        callStack.push(fblock);
-    }
+void DataManager::pushFunction(FunctionBlock * fblock)
+{
+    callStack.push(fblock);
+}
 
-    FunctionBlock * DataManager::poptopFunction()
-    {
-        FunctionBlock * fblock = callStack.top();
-        callStack.pop();
-        return fblock;
-    }
+FunctionBlock * DataManager::poptopFunction()
+{
+    FunctionBlock * fblock = callStack.top();
+    callStack.pop();
+    return fblock;
+}
 
-    FunctionBlock * DataManager::topFunction()
+FunctionBlock * DataManager::topFunction()
+{
+    if (callStack.empty())
     {
-        if (callStack.empty())
-        {
-            return nullptr;
-        }
-        return callStack.top();
+        return nullptr;
     }
+    return callStack.top();
+}
 
-    void DataManager::popFunction()
-    {
-        callStack.pop();
-    }
+void DataManager::popFunction()
+{
+    callStack.pop();
+}
 
-    TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists)
-    {
-        types::InternalType * pIT;
-        return getSymInScilabContext(gvn, sym, exists, pIT);
-    }
+TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists)
+{
+    types::InternalType * pIT;
+    return getSymInScilabContext(gvn, sym, exists, pIT);
+}
 
-    TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, types::InternalType *& pIT)
-    {
-        bool exists;
-        return getSymInScilabContext(gvn, sym, exists, pIT);
-    }
+TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, types::InternalType *& pIT)
+{
+    bool exists;
+    return getSymInScilabContext(gvn, sym, exists, pIT);
+}
 
-    TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists, types::InternalType *& pIT)
+TIType DataManager::getSymInScilabContext(GVN & gvn, const symbol::Symbol & sym, bool & exists, types::InternalType *& pIT)
+{
+    pIT = symbol::Context::getInstance()->get(sym);
+    if (pIT)
     {
-        pIT = symbol::Context::getInstance()->get(sym);
-        if (pIT)
+        exists = true;
+        if (pIT->isGenericType())
         {
-            exists = true;
-            if (pIT->isGenericType())
+            types::GenericType * pGT = static_cast<types::GenericType *>(pIT);
+            switch (pIT->getType())
             {
-                types::GenericType * pGT = static_cast<types::GenericType *>(pIT);
-                switch (pIT->getType())
-                {
                 case types::InternalType::ScilabInt8:
                     return TIType(gvn, TIType::Type::INT8, pGT->getRows(), pGT->getCols());
                 case types::InternalType::ScilabUInt8:
@@ -263,12 +263,12 @@ namespace analysis
                     return TIType(gvn, TIType::Type::SPARSE, pGT->getRows(), pGT->getCols());
                 default:
                     return TIType(gvn, TIType::Type::UNKNOWN, pGT->getRows(), pGT->getCols());
-                }
             }
-            else if (pIT->isCallable())
+        }
+        else if (pIT->isCallable())
+        {
+            switch (pIT->getType())
             {
-                switch (pIT->getType())
-                {
                 case types::InternalType::ScilabFunction:
                     return TIType(gvn, TIType::Type::FUNCTION);
                 case types::InternalType::ScilabMacro:
@@ -277,52 +277,52 @@ namespace analysis
                     return TIType(gvn, TIType::Type::MACROFILE);
                 case types::InternalType::ScilabLibrary:
                     return TIType(gvn, TIType::Type::LIBRARY);
-                }
             }
         }
-
-        exists = false;
-        return TIType(gvn);
     }
 
-    TIType DataManager::getType(const symbol::Symbol & sym, const bool global)
+    exists = false;
+    return TIType(gvn);
+}
+
+TIType DataManager::getType(const symbol::Symbol & sym, const bool global)
+{
+    Block * parent = getCurrent();
+    tools::SymbolMap<Info>::iterator it;
+    Block * block = parent->getDefBlock(sym, it, global);
+    if (block)
     {
-        Block * parent = getCurrent();
-        tools::SymbolMap<Info>::iterator it;
-        Block * block = parent->getDefBlock(sym, it, global);
-        if (block)
-        {
-            return it->second.type;
-        }
-        else
-        {
-            bool exists;
-            return DataManager::getSymInScilabContext(getGVN(), sym, exists);
-        }
+        return it->second.type;
     }
-
-    Info & DataManager::getInfo(const symbol::Symbol & sym)
+    else
     {
-        tools::SymbolMap<Info>::iterator it;
-        Block * block = current->getDefBlock(sym, it, false);
-        if (block)
-        {
-            return it->second;
-        }
-
-        // The sym is not in this DataManager... try in the Scilab's context
-        return current->setDefaultData(sym);
+        bool exists;
+        return DataManager::getSymInScilabContext(getGVN(), sym, exists);
     }
+}
 
-    std::wostream & operator<<(std::wostream & out, const DataManager & dm)
+Info & DataManager::getInfo(const symbol::Symbol & sym)
+{
+    tools::SymbolMap<Info>::iterator it;
+    Block * block = current->getDefBlock(sym, it, false);
+    if (block)
     {
-        out << L"DataManager:" << std::endl
-            << L"Globals: ";
+        return it->second;
+    }
 
-        tools::printSet(dm.globals, out);
-        out << std::endl << *dm.root;
+    // The sym is not in this DataManager... try in the Scilab's context
+    return current->setDefaultData(sym);
+}
 
-        return out;
-    }
+std::wostream & operator<<(std::wostream & out, const DataManager & dm)
+{
+    out << L"DataManager:" << std::endl
+        << L"Globals: ";
+
+    tools::printSet(dm.globals, out);
+    out << std::endl << *dm.root;
+
+    return out;
+}
 
 } // namespace analysis
diff --git a/scilab/modules/ast/src/cpp/analysis/DollarInfo.cpp b/scilab/modules/ast/src/cpp/analysis/DollarInfo.cpp
new file mode 100644 (file)
index 0000000..167d222
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#include "DollarInfo.hxx"
+#include "simplevar.hxx"
+
+namespace analysis
+{
+
+std::wostream & operator<<(std::wostream & out, const DollarInfo & di)
+{
+    out << L"$ in " << di.var.getSymbol() << L" at index " << di.index;
+    return out;
+}
+}
index 0688caa..ca1955f 100644 (file)
@@ -105,9 +105,9 @@ MacroOut FunctionBlock::getOuts(CompleteMacroSignature & cms)
         Block * block = getDefBlock(*s, it, false);
         if (block == this)
         {
-           const TIType & ty = it->second.type;
-           const SymbolicDimension rows(cmsGVN, cmsGVN.getValue(*ty.rows.getValue()->poly));
-           const SymbolicDimension cols(cmsGVN, cmsGVN.getValue(*ty.cols.getValue()->poly));
+            const TIType & ty = it->second.type;
+            const SymbolicDimension rows(cmsGVN, cmsGVN.getValue(*ty.rows.getValue()->poly));
+            const SymbolicDimension cols(cmsGVN, cmsGVN.getValue(*ty.cols.getValue()->poly));
             v.emplace_back(TIType(cmsGVN, ty.type, rows, cols));
         }
         else
@@ -115,10 +115,10 @@ MacroOut FunctionBlock::getOuts(CompleteMacroSignature & cms)
             addGlobal(*s);
             if (block)
             {
-               const TIType & ty = it->second.type;
-               const SymbolicDimension rows(cmsGVN, cmsGVN.getValue(*ty.rows.getValue()->poly));
-               const SymbolicDimension cols(cmsGVN, cmsGVN.getValue(*ty.cols.getValue()->poly));
-               v.emplace_back(TIType(cmsGVN, ty.type, rows, cols));
+                const TIType & ty = it->second.type;
+                const SymbolicDimension rows(cmsGVN, cmsGVN.getValue(*ty.rows.getValue()->poly));
+                const SymbolicDimension cols(cmsGVN, cmsGVN.getValue(*ty.cols.getValue()->poly));
+                v.emplace_back(TIType(cmsGVN, ty.type, rows, cols));
             }
             else
             {
@@ -295,7 +295,9 @@ std::wostream & operator<<(std::wostream & out, const FunctionBlock & fblock)
         }
     }
 
-    out << L'\n';
+    out << L'\n'
+        << L"Constraint Manager\n" << fblock.constraintManager << L'\n';
+
     const std::map<TypeLocal, std::stack<int>> & temps = fblock.getTemp();
     if (temps.empty())
     {
index 601bd02..6f048d6 100644 (file)
@@ -37,19 +37,18 @@ bool AnalysisVisitor::analyzeIndices(TIType & type, ast::CallExp & ce)
     SymbolicDimension first, second;
     bool safe, ret;
 
-    argIndices.emplace(static_cast<ast::SimpleVar &>(ce.getName()).getSymbol(), 1);
+    argIndices.emplace(static_cast<ast::SimpleVar &>(ce.getName()), size, 1);
     if (size == 1)
     {
         // when there is one argument, a(?) is equivalent to A(?,1)
         // where A = matrix(a, r_a * c_a, 1)
 
         SymbolicDimension rows(type.rows);
-        second = SymbolicDimension(getGVN(), 1.);
+        second = SymbolicDimension(getGVN(), 1);
         if (type.cols != 1)
         {
             rows *= type.cols;
         }
-
         ret = getDimension(rows, *args.front(), safe, first);
     }
     else
index 1ccc2b8..b557ab6 100644 (file)
@@ -95,6 +95,12 @@ bool Info::isknown() const
     return local == Local::INFO_TRUE;
 }
 
+bool Info::isAnInt() const
+{
+    return constant.getGVNValue() != nullptr || getRange().isValid();
+}
+
+
 const symbol::Symbol & Info::getRightSym(ast::Exp * exp)
 {
     return static_cast<const ast::SimpleVar &>(static_cast<const ast::AssignExp *>(exp)->getRightExp()).getSymbol();
@@ -111,7 +117,7 @@ std::wostream & operator<<(std::wostream & out, const Info & info)
         << (info.R ? L"T" : L"F")
         << (info.W ? L"T" : L"F")
         << (info.O ? L"T" : L"F")
-        << L" - int:" << (info.isint ? L"T" : L"F")
+        << L" - int:" << (info.isAnInt() ? L"T" : L"F")
         << L" - local:" << (info.local == Info::Local::INFO_TRUE ? L"T" : (info.local == Info::Local::INFO_FALSE ? L"F" : L"U"))
         << L" - cleared:" << (info.cleared ? L"T" : L"F")
         << L" - exists:" << (info.exists ? L"T" : L"F")
index 2f34287..1b6db23 100644 (file)
@@ -19,19 +19,29 @@ bool LoopBlock::requiresAnotherTrip()
 {
     if (first)
     {
+        bool ret = false;
         for (auto & p : symMap)
         {
             tools::SymbolMap<Info>::iterator it;
-            Block * block = getParent()->getDefBlock(p.first, it, false);
-            if (block)
+            if (p.second.type.type != TIType::UNKNOWN)
             {
-                const Info & info = it->second;
-                if (info.type != p.second.type || !info.data->same(p.second.data))
+                Block * block = getParent()->getDefBlock(p.first, it, false);
+                if (block)
                 {
-                    return true;
+                    const Info & info = it->second;
+                    if (info.type != p.second.type || (info.type.type == TIType::DOUBLE && info.isAnInt() != p.second.isAnInt()))
+                    {
+                        getParent()->getExp()->getDecorator().addPromotion(p.first, info.type, p.second.type);
+                        ret = true;
+                    }
+                    else if (!info.data->same(p.second.data))
+                    {
+                        ret = true;
+                    }
                 }
             }
         }
+        return ret;
     }
     else
     {
@@ -136,7 +146,7 @@ void LoopBlockHead::finalize()
         }
 
         // ii) clone is in first and in second so we clone the data at each iteration
-        // iii) clone is only in second so we clone the daat at each iteration except for the first one
+        // iii) clone is only in second so we clone the data at each iteration except for the first one
         //      => for now, we clone at each iteration (TODO: improve that in removing clone at the first iteration)
         for (auto & p : inBoth)
         {
index 0440d10..b0dff24 100644 (file)
 namespace analysis
 {
 
-    bool MultivariateMonomial::contains(const uint64_t var) const
-       {
-           return monomial.find(var) != monomial.end();
-       }
-    
-    bool MultivariateMonomial::checkVariable(const uint64_t max) const
-    {
-       return std::prev(monomial.end())->var <= max;
-    }
+bool MultivariateMonomial::contains(const uint64_t var) const
+{
+    return monomial.find(var) != monomial.end();
+}
 
-    unsigned int MultivariateMonomial::exponent() const
-    {
-        unsigned int exp = 0;
-        for (const auto & ve : monomial)
-        {
-            exp += ve.exp;
-        }
-        return exp;
-    }
+bool MultivariateMonomial::checkVariable(const uint64_t max) const
+{
+    return std::prev(monomial.end())->var <= max;
+}
 
-    MultivariateMonomial & MultivariateMonomial::add(const VarExp & ve)
+unsigned int MultivariateMonomial::exponent() const
+{
+    unsigned int exp = 0;
+    for (const auto & ve : monomial)
     {
-        Monomial::iterator i = monomial.find(ve);
-        if (i == monomial.end())
-        {
-            monomial.insert(ve);
-        }
-        else
-        {
-            i->exp += ve.exp;
-        }
-        return *this;
+        exp += ve.exp;
     }
+    return exp;
+}
 
-    MultivariateMonomial & MultivariateMonomial::add(VarExp && ve)
+MultivariateMonomial & MultivariateMonomial::add(const VarExp & ve)
+{
+    Monomial::iterator i = monomial.find(ve);
+    if (i == monomial.end())
     {
-        Monomial::iterator i = monomial.find(ve);
-        if (i == monomial.end())
-        {
-            monomial.emplace(std::move(ve));
-        }
-        else
-        {
-            i->exp += ve.exp;
-        }
-        return *this;
+        monomial.insert(ve);
     }
-
-    MultivariateMonomial MultivariateMonomial::operator*(const MultivariateMonomial & R) const
+    else
     {
-        MultivariateMonomial res(*this);
-        res.coeff *= R.coeff;
-        for (const auto & ve : R.monomial)
-        {
-            res.add(ve);
-        }
-        return res;
+        i->exp += ve.exp;
     }
+    return *this;
+}
 
-    MultivariateMonomial & MultivariateMonomial::operator*=(const MultivariateMonomial & R)
+MultivariateMonomial & MultivariateMonomial::add(VarExp && ve)
+{
+    Monomial::iterator i = monomial.find(ve);
+    if (i == monomial.end())
     {
-        coeff *= R.coeff;
-        for (const auto & ve : R.monomial)
-        {
-            add(ve);
-        }
-        return *this;
+        monomial.emplace(std::move(ve));
     }
-
-    MultivariateMonomial operator*(const int64_t L, const MultivariateMonomial & R)
+    else
     {
-        return R * L;
+        i->exp += ve.exp;
     }
+    return *this;
+}
 
-    MultivariateMonomial MultivariateMonomial::operator*(const int64_t R) const
+MultivariateMonomial MultivariateMonomial::operator*(const MultivariateMonomial & R) const
+{
+    MultivariateMonomial res(*this);
+    res.coeff *= R.coeff;
+    for (const auto & ve : R.monomial)
     {
-        MultivariateMonomial res(*this);
-        res.coeff *= R;
-        return res;
+        res.add(ve);
     }
+    return res;
+}
 
-    MultivariateMonomial & MultivariateMonomial::operator*=(const int64_t R)
+MultivariateMonomial & MultivariateMonomial::operator*=(const MultivariateMonomial & R)
+{
+    coeff *= R.coeff;
+    for (const auto & ve : R.monomial)
     {
-        coeff *= R;
-        return *this;
+        add(ve);
     }
+    return *this;
+}
 
-    MultivariateMonomial MultivariateMonomial::operator/(const int64_t R) const
-    {
-        MultivariateMonomial res(*this);
-        res.coeff /= R;
-        return res;
-    }
+MultivariateMonomial operator*(const int64_t L, const MultivariateMonomial & R)
+{
+    return R * L;
+}
+
+MultivariateMonomial MultivariateMonomial::operator*(const int64_t R) const
+{
+    MultivariateMonomial res(*this);
+    res.coeff *= R;
+    return res;
+}
+
+MultivariateMonomial & MultivariateMonomial::operator*=(const int64_t R)
+{
+    coeff *= R;
+    return *this;
+}
 
-    MultivariateMonomial & MultivariateMonomial::operator/=(const int64_t R)
+MultivariateMonomial MultivariateMonomial::operator/(const int64_t R) const
+{
+    MultivariateMonomial res(*this);
+    res.coeff /= R;
+    return res;
+}
+
+MultivariateMonomial & MultivariateMonomial::operator/=(const int64_t R)
+{
+    coeff /= R;
+    return *this;
+}
+
+MultivariateMonomial MultivariateMonomial::operator^(unsigned int R) const
+{
+    MultivariateMonomial res(*this);
+    if (R > 1)
     {
-        coeff /= R;
-        return *this;
+        coeff = std::pow(coeff, R);
+        for (auto & ve : res.monomial)
+        {
+            ve.exp *= R;
+        }
     }
+    return res;
+}
+
+bool MultivariateMonomial::operator==(const MultivariateMonomial & R) const
+{
+    return coeff == R.coeff && monomial == R.monomial;
+}
 
-    MultivariateMonomial MultivariateMonomial::operator^(unsigned int R) const
+const std::wstring MultivariateMonomial::print(const std::map<uint64_t, std::wstring> & vars) const
+{
+    std::wostringstream wos;
+    if (coeff == -1 || coeff == 1)
     {
-        MultivariateMonomial res(*this);
-        if (R > 1)
+        if (coeff == -1)
+        {
+            wos << L'-';
+        }
+        if (!monomial.empty())
         {
-            coeff = std::pow(coeff, R);
-            for (auto & ve : res.monomial)
+            wos << monomial.begin()->print(vars);
+            for (auto i = std::next(monomial.begin()), e = monomial.end(); i != e; ++i)
             {
-                ve.exp *= R;
+                wos << L"*" << i->print(vars);
             }
         }
-        return res;
     }
-
-    bool MultivariateMonomial::operator==(const MultivariateMonomial & R) const
+    else
     {
-        return coeff == R.coeff && monomial == R.monomial;
+        wos << coeff;
+        for (const auto & ve : monomial)
+        {
+            wos << L"*" << ve.print(vars);
+        }
     }
+    return wos.str();
+}
 
-    const std::wstring MultivariateMonomial::print(const std::map<uint64_t, std::wstring> & vars) const
-    {
-        std::wostringstream wos;
-       if (coeff == 1)
-       {
-           if (!monomial.empty())
-           {
-               wos << monomial.begin()->print(vars);
-               for (auto i = std::next(monomial.begin()), e = monomial.end(); i != e; ++i)
-               {
-                   wos << L"*" << i->print(vars);
-               }
-           }
-       }
-       else
-       {
-           wos << coeff;
-           for (const auto & ve : monomial)
-           {
-               wos << L"*" << ve.print(vars);
-           }
-       }
-        return wos.str();
-    }
+std::wostream & operator<<(std::wostream & out, const MultivariateMonomial & m)
+{
+    const std::map<uint64_t, std::wstring> vars;
+    out << m.print(vars);
+
+    return out;
+}
 
-    std::wostream & operator<<(std::wostream & out, const MultivariateMonomial & m)
+bool MultivariateMonomial::Compare::operator()(const MultivariateMonomial & L, const MultivariateMonomial & R) const
+{
+    const unsigned int le = L.exponent();
+    const unsigned int re = R.exponent();
+    if (le < re)
     {
-       if (m.coeff == 1)
-       {
-           if (!m.monomial.empty())
-           {
-               out << *m.monomial.begin();
-               for (auto i = std::next(m.monomial.begin()), e = m.monomial.end(); i != e; ++i)
-               {
-                   out << L"*" << *i;
-               }
-           }
-       }
-       else
-       {
-           out << m.coeff;
-           for (const auto & ve : m.monomial)
-           {
-               out << L"*" << ve;
-           }
-       }
-        return out;
+        return true;
     }
-
-    bool MultivariateMonomial::Compare::operator()(const MultivariateMonomial & L, const MultivariateMonomial & R) const
+    else if (le == re)
     {
-            const unsigned int le = L.exponent();
-            const unsigned int re = R.exponent();
-            if (le < re)
+        const unsigned int ls = static_cast<unsigned int>(L.monomial.size());
+        const unsigned int rs = static_cast<unsigned int>(R.monomial.size());
+        if (ls > rs)
+        {
+            return true;
+        }
+        else if (ls == rs)
+        {
+            for (Monomial::const_iterator i = L.monomial.begin(), j = R.monomial.begin(), e = L.monomial.end(); i != e; ++i, ++j)
             {
-                return true;
+                if (VarExp::Compare()(*i, *j))
+                {
+                    return true;
+                }
+                else if (!VarExp::Eq()(*i, *j))
+                {
+                    return false;
+                }
             }
-            else if (le == re)
+
+            for (Monomial::const_iterator i = L.monomial.begin(), j = R.monomial.begin(), e = L.monomial.end(); i != e; ++i, ++j)
             {
-                const unsigned int ls = static_cast<unsigned int>(L.monomial.size());
-                const unsigned int rs = static_cast<unsigned int>(R.monomial.size());
-                if (ls > rs)
+                if (i->exp < j->exp)
                 {
                     return true;
                 }
-                else if (ls == rs)
+                else if (i->exp > j->exp)
                 {
-                    for (Monomial::const_iterator i = L.monomial.begin(), j = R.monomial.begin(), e = L.monomial.end(); i != e; ++i, ++j)
-                    {
-                        if (VarExp::Compare()(*i, *j))
-                        {
-                            return true;
-                        }
-                        else if (!VarExp::Eq()(*i, *j))
-                        {
-                            return false;
-                        }
-                    }
-
-                    for (Monomial::const_iterator i = L.monomial.begin(), j = R.monomial.begin(), e = L.monomial.end(); i != e; ++i, ++j)
-                    {
-                        if (i->exp < j->exp)
-                        {
-                            return true;
-                        }
-                        else if (i->exp > j->exp)
-                        {
-                            return false;
-                        }
-                    }
-
+                    return false;
                 }
             }
-            return false;
+
         }
+    }
+    return false;
+}
 
 } // namespace analysis
index ab564f2..1cd8ec8 100644 (file)
@@ -707,24 +707,52 @@ bool MultivariatePolynomial::isCoeffNegative(const bool checkConstant) const
 const std::wstring MultivariatePolynomial::print(const std::map<uint64_t, std::wstring> & vars) const
 {
     std::wostringstream wos;
-    wos << constant;
-    std::set<MultivariateMonomial, MultivariateMonomial::Compare> s(polynomial.begin(), polynomial.end());
-    for (const auto & m : s)
+    if (polynomial.empty())
+    {
+        wos << constant;
+    }
+    else
     {
-        wos << L" + " << m.print(vars);
+        std::set<MultivariateMonomial, MultivariateMonomial::Compare> s(polynomial.begin(), polynomial.end());
+        auto i = s.begin();
+        if (constant)
+        {
+            wos << constant;
+            if (i->coeff >= 0)
+            {
+                wos << L'+' << i->print(vars);
+            }
+            else
+            {
+                wos << i->print(vars);
+            }
+        }
+        else
+        {
+            wos << i->print(vars);
+        }
+
+        for (i = std::next(s.begin()); i != s.end(); ++i)
+        {
+            if (i->coeff >= 0)
+            {
+                wos << L'+' << i->print(vars);
+            }
+            else
+            {
+                wos << i->print(vars);
+            }
+        }
     }
+
     return wos.str();
 }
 
 std::wostream & operator<<(std::wostream & out, const MultivariatePolynomial & p)
 {
     const std::map<uint64_t, std::wstring> vars;
-    out << p.constant;
-    std::set<MultivariateMonomial, MultivariateMonomial::Compare> s(p.polynomial.begin(), p.polynomial.end());
-    for (const auto & m : s)
-    {
-        out << L" + " << m.print(vars);
-    }
+    out << p.print(vars);
+
     return out;
 }
 
index bc9d7c7..e8b8381 100644 (file)
@@ -27,17 +27,24 @@ void AnalysisVisitor::visit(ast::AssignExp & e)
         {
             // We have A = B (so the data associated to b is shared with a)
             const symbol::Symbol & symR = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
-            const TIType & Rtype = getSymInfo(symR).getType();
-            getDM().share(sym, symR, Rtype, &e);
-            static_cast<ast::SimpleVar &>(e.getRightExp()).getDecorator().setResult(Rtype);
-            static_cast<ast::SimpleVar &>(e.getLeftExp()).getDecorator().setResult(Rtype);
+            Info & info = getSymInfo(symR);
+            const TIType & Rtype = info.getType();
+            Result & resL = e.getLeftExp().getDecorator().setResult(Rtype);
+            resL.setConstant(info.getConstant());
+            resL.setRange(info.getRange());
+            Result & resR = e.getRightExp().getDecorator().setResult(Rtype);
+            resR.setConstant(info.getConstant());
+            resR.setRange(info.getRange());
+            getDM().share(sym, symR, Rtype, resR.isAnInt(), &e);
         }
         else
         {
+            // apply the ConstantVisitor
+            cv.setLHS(1);
+            e.getRightExp().accept(cv);
+
             if (e.getRightExp().isCallExp()) // A = foo(...)
             {
-                // apply the ConstantVisitor
-                e.getRightExp().accept(cv);
                 if (e.getRightExp().isCallExp())
                 {
                     visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ 1);
@@ -49,8 +56,6 @@ void AnalysisVisitor::visit(ast::AssignExp & e)
             }
             else // A = 1 + 2
             {
-                cv.setLHS(1);
-                e.getRightExp().accept(cv);
                 e.getRightExp().accept(*this);
             }
 
@@ -61,11 +66,15 @@ void AnalysisVisitor::visit(ast::AssignExp & e)
             e.getDecorator().safe = true;
 
             // Don't remove temp: because the value is transfered to LHS
-            //getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
+            getDM().releaseTmp(RR.getTempId(), nullptr);//&e.getRightExp());
         }
     }
     else if (e.getLeftExp().isCallExp()) // A(12) = ...
     {
+        // apply the ConstantVisitor
+        cv.setLHS(1);
+        e.getRightExp().accept(cv);
+
         ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
         if (ce.getName().isSimpleVar())
         {
index b06cbf8..af77664 100644 (file)
@@ -21,13 +21,20 @@ void AnalysisVisitor::visit(ast::DollarVar & e)
     Result & res = e.getDecorator().setResult(TIType(dm.getGVN(), TIType::POLYNOMIAL, 1, 1));
     res.getConstant() = getGVN().getValue(symbol::Symbol(L"$"));
 
-    if (!argIndices.empty())
+    if (argIndices.empty())
+    {
+        Result & res = e.getDecorator().setResult(TIType(dm.getGVN(), TIType::POLYNOMIAL, 1, 1));
+        res.getConstant() = getGVN().getValue(symbol::Symbol(L"$"));
+        setResult(res);
+    }
+    else
     {
         // we have something like A(1, $ - 1)
         e.getDecorator().setDollarInfo(argIndices.top());
+        Result & res = e.getDecorator().setResult(TIType(dm.getGVN(), TIType::DOUBLE, 1, 1));
+        res.getConstant() = getGVN().getValue(symbol::Symbol(L"$"));
+        setResult(res);
     }
-
-    setResult(res);
 }
 
 } // namespace analysis
index e8dd04b..fed5f41 100644 (file)
@@ -28,6 +28,7 @@ void AnalysisVisitor::visit(ast::VarDec & e)
         Result & res = getResult();
         Info & info = dm.define(sym, res.getType(), res.isAnInt(), &e);
         info.setRange(res.getRange());
+        e.getDecorator().res = res;
     }
 }
 
diff --git a/scilab/modules/ast/src/cpp/analysis/VisitWhileExp.cpp b/scilab/modules/ast/src/cpp/analysis/VisitWhileExp.cpp
new file mode 100644 (file)
index 0000000..9c1b67a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#include "AnalysisVisitor.hxx"
+
+namespace analysis
+{
+
+void AnalysisVisitor::visit(ast::WhileExp & e)
+{
+    logger.log(L"WhileExp", e.getLocation());
+    loops.push(&e);
+
+    dm.addBlock(Block::LOOP, &e);
+    e.getTest().accept(*this);
+    dm.releaseTmp(getResult().getTempId(), &e.getTest());
+    dm.addBlock(Block::NORMAL, &e.getBody());
+    e.getBody().accept(*this);
+
+    if (dm.requiresAnotherTrip())
+    {
+        dm.finalizeBlock();
+        dm.addBlock(Block::NORMAL, &e.getBody());
+
+        // Since the variables in the test have maybe changed (e.g. a double-int became a double)
+        // we need to re-analyze it to take into account these changes
+        e.getTest().accept(*this);
+        dm.releaseTmp(getResult().getTempId(), &e.getTest());
+
+        e.getBody().accept(*this);
+
+        if (dm.requiresAnotherTrip())
+        {
+            std::wcerr << "Invalid forexp: types or refcount are not the same before and after the loop" << std::endl;
+        }
+    }
+
+    dm.finalizeBlock();
+    dm.finalizeBlock();
+
+    loops.pop();
+}
+
+} // namespace analysis