Notes on copies of source code inside the generated codeΒΆ

   Distinguish "Source code" from "Generated code",
   and in this "Generated code" distinguish "Diff code" from "Primal code":
   -- The "Source code" is the original code given to Tapenade.
     By definition, Tapenade does not modify nor touch the Source code.
   -- The "Generated code" is the code produced by Tapenade.
     It probably contains differentiated code (that we will call "Diff code")
     and in many cases also non-differentiated-copies (that we will
     call "Primal code") of parts of the Source code.

   The complete Source code is made of nested Pieces, that form a tree of Pieces.
   Decisions on regeneration apply to the nodes of this tree of Pieces.
   A Piece can be: "code root", "language root", "file (i.e. Translation Unit)",
     "Class", "Module", "User Procedure", "Main or Program procedure"
   "code root", "language root", "file", and "Module" behave the same and we will call them "Package".
   The Fortran "Program" or the C "main" are a kind of "Procedure".
   External or Intrinsic procedures are not considered as Pieces (i.e. "Procedure" Pieces),
    since they are only used and not defined in the Source code.
   Interface's are considered as "Procedures" as may be differentiated into Diff Interfaces.
   ==> Therefore 3 sorts of Pieces: "Package" (M), "Class" (C), "Procedure" (F)
   The Pieces almost correspond to Tapenade's Unit's except
    -- External or Intrinsic, that are Units but not Pieces
    -- "code root" and each "language root", that are Pieces and not Units

   -- a Class C can contain pieces of sorts C or F (plus possible V and T)
   -- a Package M can contain pieces of sorts C or F (plus possible V and T)
     and we are unsure about sub-packages M, but maybe yes some day?
     Also, as we said Roots and Files are packages, then these packages have sub-packages M.
  -- a Procedure F can contain pieces of sort F only.

   The basis cause for regeneration of diff or of primal code is activity
   of Variables (V), from which we deduce activity of other things:
   -- A Variable (V) is Active if a derivative variable is needed for V,
     either because ADActivityAnalysis decided so (true derivative needed),
     or because ReqExplicit analysis decided so (derivative pointer needed).
     In particular, this holds for Variables in "context" procedures in "context mode".
   -- A (user) Type (T) is Active if some variable V of type T is Active
     and the differentiated type T' is different from T.
     Special case: if "-nooptim difftypes", T' is always the same as T and therefore T is not Active.
   -- A Procedure (F) is Active if it has at least one Active input or
     one Active output for one activity pattern (cf class ActivityPattern.java).
     In particular, "context" procedures in "context mode" are Active.
   -- A Class (C) is Active if it contains a Procedure (F) that is Active
     or if it has a field Variable or Type which is Active.
   -- A Package (M) is Active if it contains a Procedure (F) that is Active
     or if it defines a Variable or Type which is Active.

   Recursively, a Procedure, Class, or Package is said to "Contain Active" if it contains
    a Piece (at any depth below it) that is Active or Contains Active.
   Notation: a Piece is "Active*" iff it is Active or Contains Active

   A Procedure, Class, or Package is said to "Import Active" if it "imports" (e.g. F90 "USE",
    or Class inheritance ...) a Piece that is Active* or that Imports Active.
    Note: we don't say that a procedure "Imports Active" by e.g. calling an Active procedure,
    because that would render context procedures active and we want this only in "-context" mode,
    and if in "-context" mode, then the calling context procedures are already plain "Active".

   We also introduce a similar fixed-point to find "Import Primal", except that in this case, we also say
    that a procedure is "Import Primal" if it is caught in a call chain from a Primal* procedure
    (or from a procedure "called in Primal form") to a Primal* procedure.

   For a Piece of the "Source code", the generation decision can be to generate in the "Generated code":
    - NOTHING:     nothing
    - PRIMAL:      only one Piece that contains the "Primal code", and no "Diff code"
    - DIFF:        only one Piece that contains the "Diff code", and no copy "Primal code".
    - DIFF+PRIMAL: one Piece that contains the "Diff code" plus another Piece that contains the
                   copy "Primal code" ("separate"), or a single Piece that contains both ("together").
   After taking decisions DIFF+PRIMAL or PRIMAL, the "Generated code" must
    never refer to or call the original Piece from the Source Code.
    Otherwise (NOTHING or DIFF) the "Generated code" must link to the Source Code at runtime.
   If only DIFF+PRIMAL or PRIMAL decisions are chosen,
    then the "Generated code" can be executed standalone (if the primal can).

   For a Class (C) OR a Package (M),
     if (it is Active* OR Imports Active) {
        DIFF+PRIMAL (together)
     } else {
        if (-nooptim stripPrimalModules) {
           PRIMAL
        } else {
           NOTHING
        }
     }
   (Rationale: we cannot have a separate Primal (C or M) and a separate Diff (C or M) because they
    must share their primal variable fields or globals)

   FOR a Procedure (F),
     if (F is Active*) {
       if (F is called in the "Generated code" OR -nooptim stripPrimalCode OR F Imports Active
            OR F is contained in Active* OR F is in a C file with globals) {
          DIFF+PRIMAL (separate)
       } else {
          DIFF
     } else {
       if (F is called in the "Generated code" OR -nooptim stripPrimalCode OR F Imports Active
            OR F is contained in Active* OR F is in a C file with globals) {
          PRIMAL
       } else {
          NOTHING
       }
     }
   (Rationale: We must split Primal P and Diff P, because each one may be called.
    We can do so (split Primal P and Diff P) because they need not share variables.
    (except for "save" variables => possible bug, must be fixed or warning: TODO)
    If F is contained in Active*, then Diff and Primal of F must be in the same Diff container
     because they must share globals variables of this container ;
     IOW the Generated code cannot link to the Primal F from the Source code ;
     same thing if F is in a C file that declares globals)