- stop_phase = case todo of
- StopBefore As | split -> SplitAs
-#ifdef ILX
- | real_lang == HscILX -> Ilasm
-#endif
- StopBefore phase -> phase
- DoMkDependHS -> Ln
- DoLink -> Ln
- DoMkDLL -> Ln
- ----------- ----- ---- --- -- -- - - -
-
- -- this shouldn't happen.
- when (start_phase /= Ln && start_phase `notElem` pipeline)
- (throwDyn (CmdLineError ("can't find starting phase for "
- ++ filename)))
- -- if we can't find the phase we're supposed to stop before,
- -- something has gone wrong. This test carefully avoids the
- -- case where we aren't supposed to do any compilation, because the file
- -- is already in linkable form (for example).
--- hPutStrLn stderr (show ((start_phase `elem` pipeline,stop_phase /= Ln,stop_phase `notElem` pipeline), start_phase, stop_phase, pipeline,todo))
--- hFlush stderr
- when (start_phase `elem` pipeline &&
- (stop_phase /= Ln && stop_phase `notElem` pipeline))
- (do
- throwDyn (UsageError
- ("flag `" ++ stop_flag
- ++ "' is incompatible with source file `"
- ++ filename ++ "'" ++ show pipeline ++ show stop_phase)))
- let
- -- .o and .hc suffixes can be overriden by command-line options:
- myPhaseInputExt HCc | Just s <- hcsuf = s
- myPhaseInputExt Ln = osuf
- myPhaseInputExt other = phaseInputExt other
-
- annotatePipeline
- :: [Phase] -- raw pipeline
- -> Phase -- phase to stop before
- -> [(Phase, IntermediateFileType, String{-file extension-})]
- annotatePipeline [] _ = []
- annotatePipeline (Ln:_) _ = []
- annotatePipeline (phase:next_phase:ps) stop =
- (phase, keep_this_output, myPhaseInputExt next_phase)
- : annotatePipeline (next_phase:ps) stop
- where
- keep_this_output
- | next_phase == stop
- = if persistent_output then Persistent else Temporary
- | otherwise
- = case next_phase of
- Ln -> Persistent
- Mangle | keep_raw_s -> Persistent
- As | keep_s -> Persistent
- HCc | keep_hc -> Persistent
-#ifdef ILX
- Ilx2Il | keep_ilx -> Persistent
- Ilasm | keep_il -> Persistent
-#endif
- _other -> Temporary
-
- -- add information about output files to the pipeline
- -- the suffix on an output file is determined by the next phase
- -- in the pipeline, so we add linking to the end of the pipeline
- -- to force the output from the final phase to be a .o file.
-
- annotated_pipeline = annotatePipeline (pipeline ++ [Ln]) stop_phase
-
- phase_ne p (p1,_,_) = (p1 /= p)
- ----------- ----- ---- --- -- -- - - -
-
- return (
- takeWhile (phase_ne stop_phase ) $
- dropWhile (phase_ne start_phase) $
- annotated_pipeline
- )
-
-
-runPipeline
- :: [ (Phase, IntermediateFileType, String) ] -- phases to run
- -> (String,String) -- input file
- -> Bool -- doing linking afterward?
- -> Bool -- take into account -o when generating output?
- -> IO (String, String) -- return final filename
-
-runPipeline pipeline (input_fn,suffix) do_linking use_ofile
- = pipeLoop pipeline (input_fn,suffix) do_linking use_ofile basename suffix
- where (basename, _) = splitFilename input_fn
-
-pipeLoop [] input_fn _ _ _ _ = return input_fn
-pipeLoop (all_phases@((phase, keep, o_suffix):phases))
- (input_fn,real_suff) do_linking use_ofile orig_basename orig_suffix
- = do
+-- -----------------------------------------------------------------------------
+-- Each phase in the pipeline returns the next phase to execute, and the
+-- name of the file in which the output was placed.
+--
+-- We must do things dynamically this way, because we often don't know
+-- what the rest of the phases will be until part-way through the
+-- compilation: for example, an {-# OPTIONS -fasm #-} at the beginning
+-- of a source file can change the latter stages of the pipeline from
+-- taking the via-C route to using the native code generator.
+
+runPhase :: Phase
+ -> String -- basename of original input source
+ -> String -- its extension
+ -> FilePath -- name of file which contains the input to this phase.
+ -> (Phase -> Maybe ModLocation -> IO FilePath)
+ -- how to calculate the output filename
+ -> Maybe ModLocation -- the ModLocation, if we have one
+ -> IO (Maybe Phase, -- next phase
+ Maybe ModLocation, -- the ModLocation, if we have one
+ FilePath) -- output filename