Alan Zimmerman pushed to branch wip/az/ghc-cpp at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • compiler/GHC/Parser/Lexer.x
    ... ... @@ -59,7 +59,6 @@ module GHC.Parser.Lexer (
    59 59
        Token(..), lexer, lexerDbg,
    
    60 60
        ParserOpts(..), mkParserOpts,
    
    61 61
        PState (..), initParserState, initPragState,
    
    62
    -   PSavedAlrState(..), getAlrState, setAlrState,
    
    63 62
        startSkipping, stopSkipping,
    
    64 63
        P(..), ParseResult(POk, PFailed),
    
    65 64
        allocateComments, allocatePriorComments, allocateFinalComments,
    
    ... ... @@ -273,7 +272,6 @@ $tab { warnTab }
    273 272
     -- set.
    
    274 273
     
    
    275 274
     "{-" / { isNormalComment }       { nested_comment }
    
    276
    --- "/*" / { ifExtension GhcCppBit } { cpp_comment }
    
    277 275
     
    
    278 276
     -- Single-line comments are a bit tricky.  Haskell 98 says that two or
    
    279 277
     -- more dashes followed by a symbol should be parsed as a varsym, so we
    
    ... ... @@ -1351,6 +1349,7 @@ hopefully_open_brace :: Action p
    1351 1349
     hopefully_open_brace span buf len buf2
    
    1352 1350
      = do relaxed <- getBit RelaxedLayoutBit
    
    1353 1351
           ctx <- getContext
    
    1352
    +      -- See Note [GHC_CPP saved offset]
    
    1354 1353
           offset <- getOffset
    
    1355 1354
           let
    
    1356 1355
               isOK = relaxed ||
    
    ... ... @@ -1592,15 +1591,6 @@ nested_doc_comment span buf _len _buf2 = {-# SCC "nested_doc_comment" #-} withLe
    1592 1591
             dropTrailingDec "-}" = ""
    
    1593 1592
             dropTrailingDec (x:xs) = x:dropTrailingDec xs
    
    1594 1593
     
    
    1595
    -cpp_comment :: Action p
    
    1596
    -cpp_comment span buf len _buf2 = {-# SCC "cpp_comment" #-} do
    
    1597
    -  l <- getLastLocIncludingComments
    
    1598
    -  let endComment input (L _ comment) = commentEnd lexToken input (Nothing, ITblockComment comment l) buf span
    
    1599
    -  input <- getInput
    
    1600
    -  -- Include decorator in comment
    
    1601
    -  let start_decorator = reverse $ lexemeToString buf len
    
    1602
    -  cpp_comment_logic endComment start_decorator input span
    
    1603
    -
    
    1604 1594
     {-# INLINE nested_comment_logic #-}
    
    1605 1595
     -- | Includes the trailing '-}' decorators
    
    1606 1596
     -- drop the last two elements with the callback if you don't want them to be included
    
    ... ... @@ -1635,31 +1625,6 @@ nested_comment_logic endComment commentAcc input span = go commentAcc (1::Int) i
    1635 1625
             Just (_,_)   -> go ('\n':commentAcc) n input
    
    1636 1626
           Just (c,input) -> go (c:commentAcc) n input
    
    1637 1627
     
    
    1638
    -{-# INLINE cpp_comment_logic #-}
    
    1639
    --- | Includes the trailing '*/' decorators
    
    1640
    --- drop the last two elements with the callback if you don't want them to be included
    
    1641
    -cpp_comment_logic
    
    1642
    -  :: (AlexInput -> Located String -> P p (PsLocated Token))  -- ^ Continuation that gets the rest of the input and the lexed comment
    
    1643
    -  -> String -- ^ starting value for accumulator (reversed) - When we want to include a decorator '/*' in the comment
    
    1644
    -  -> AlexInput
    
    1645
    -  -> PsSpan
    
    1646
    -  -> P p (PsLocated Token)
    
    1647
    -cpp_comment_logic endComment commentAcc input span = go commentAcc (1::Int) input
    
    1648
    -  where
    
    1649
    -    go commentAcc 0 input@(AI end_loc _) = do
    
    1650
    -      let comment = reverse commentAcc
    
    1651
    -          cspan = mkSrcSpanPs $ mkPsSpan (psSpanStart span) end_loc
    
    1652
    -          lcomment = L cspan comment
    
    1653
    -      endComment input lcomment
    
    1654
    -    go commentAcc n input = case alexGetChar' input of
    
    1655
    -      Nothing -> errBrace input (psRealSpan span)
    
    1656
    -      Just ('*',input) -> case alexGetChar' input of
    
    1657
    -        Nothing  -> errBrace input (psRealSpan span)
    
    1658
    -        Just ('/',input) -> go ('/':'*':commentAcc) (n-1) input -- '/'
    
    1659
    -        Just (_,_)          -> go ('*':commentAcc) n input
    
    1660
    -      Just (c,input) -> go (c:commentAcc) n input
    
    1661
    -
    
    1662
    -
    
    1663 1628
     ghcCppSet :: P p Bool
    
    1664 1629
     ghcCppSet = do
    
    1665 1630
       exts <- getExts
    
    ... ... @@ -1775,9 +1740,12 @@ linePrag span buf len buf2 = do
    1775 1740
       usePosPrags <- getBit UsePosPragsBit
    
    1776 1741
       if usePosPrags
    
    1777 1742
         then begin line_prag2 span buf len buf2
    
    1778
    -    -- else let !src = lexemeToFastString buf len
    
    1779
    -    --      in return (L span (ITline_prag (SourceText src)))
    
    1780
    -    else nested_comment span buf len buf2
    
    1743
    +    else do
    
    1744
    +      useGhcCpp <- getBit GhcCppBit
    
    1745
    +      if useGhcCpp
    
    1746
    +        then nested_comment span buf len buf2
    
    1747
    +        else let !src = lexemeToFastString buf len
    
    1748
    +             in return (L span (ITline_prag (SourceText src)))
    
    1781 1749
     
    
    1782 1750
     -- When 'UsePosPragsBit' is not set, it is expected that we emit a token instead
    
    1783 1751
     -- of updating the position in 'PState'
    
    ... ... @@ -2166,6 +2134,7 @@ do_bol span _str _len _buf2 = do
    2166 2134
             -- See Note [Nested comment line pragmas]
    
    2167 2135
             b <- getBit InNestedCommentBit
    
    2168 2136
             if b then return (L span ITcomment_line_prag) else do
    
    2137
    +          -- See Note [GHC_CPP saved offset]
    
    2169 2138
               resetOffset
    
    2170 2139
               (pos, gen_semic) <- getOffside
    
    2171 2140
               case pos of
    
    ... ... @@ -2216,6 +2185,7 @@ maybe_layout t = do -- If the alternative layout rule is enabled then
    2216 2185
     new_layout_context :: Bool -> Bool -> Token -> Action p
    
    2217 2186
     new_layout_context strict gen_semic tok span _buf len _buf2 = do
    
    2218 2187
         _ <- popLexState
    
    2188
    +    -- See Note [GHC_CPP saved offset]
    
    2219 2189
         current_col <- getOffset
    
    2220 2190
         let offset = current_col - len
    
    2221 2191
         ctx <- getContext
    
    ... ... @@ -2670,6 +2640,7 @@ data PState a = PState {
    2670 2640
             pp :: !a,
    
    2671 2641
             -- If a CPP directive occurs in the layout context, we need to
    
    2672 2642
             -- store the prior column so any alr processing can continue.
    
    2643
    +        -- See Note [GHC_CPP saved offset]
    
    2673 2644
             pp_last_col :: !(Maybe Int)
    
    2674 2645
          }
    
    2675 2646
             -- last_loc and last_len are used when generating error messages,
    
    ... ... @@ -2684,32 +2655,6 @@ data PState a = PState {
    2684 2655
             -- of the action, it is the *current* token.  Do I understand
    
    2685 2656
             -- correctly?
    
    2686 2657
     
    
    2687
    -data PSavedAlrState = PSavedAlrState {
    
    2688
    -        -- s_warnings  :: Messages PsMessage,
    
    2689
    -        -- s_errors    :: Messages PsMessage,
    
    2690
    -        s_lex_state :: [Int],
    
    2691
    -        s_context :: [LayoutContext],
    
    2692
    -        s_alr_pending_implicit_tokens :: [PsLocated Token],
    
    2693
    -        s_alr_next_token :: Maybe (PsLocated Token),
    
    2694
    -        s_alr_last_loc :: PsSpan,
    
    2695
    -        s_alr_context :: [ALRContext],
    
    2696
    -        s_alr_expecting_ocurly :: Maybe ALRLayout,
    
    2697
    -        s_alr_justClosedExplicitLetBlock :: Bool,
    
    2698
    -        s_last_col :: Int
    
    2699
    -     }
    
    2700
    -
    
    2701
    -
    
    2702
    --- -- | Use for emulating (limited) CPP preprocessing in GHC.
    
    2703
    --- -- TODO: move this into PreProcess, and make a param on PState
    
    2704
    --- data PpState = PpState {
    
    2705
    ---         pp_defines :: !(Map String [String]),
    
    2706
    ---         pp_continuation :: ![Located Token],
    
    2707
    ---         -- pp_context :: ![PpContext],
    
    2708
    ---         pp_context :: ![Token], -- What preprocessor directive we are currently processing
    
    2709
    ---         pp_accepting :: !Bool
    
    2710
    ---      }
    
    2711
    ---     deriving (Show)
    
    2712
    -
    
    2713 2658
     data PpContext = PpContextIf [Located Token]
    
    2714 2659
         deriving (Show)
    
    2715 2660
     
    
    ... ... @@ -2825,7 +2770,7 @@ getLastBufCur = P $ \s@(PState { last_buf_cur = last_buf_cur }) -> POk s last_bu
    2825 2770
     getLastLen :: P p Int
    
    2826 2771
     getLastLen = P $ \s@(PState { last_len = last_len }) -> POk s last_len
    
    2827 2772
     
    
    2828
    --- see Note [TBD]
    
    2773
    +-- See Note [GHC_CPP saved offset]
    
    2829 2774
     getOffset :: P p Int
    
    2830 2775
     getOffset = P $ \s@(PState { pp_last_col = last_col,
    
    2831 2776
                                  loc = l}) ->
    
    ... ... @@ -2835,74 +2780,55 @@ getOffset = P $ \s@(PState { pp_last_col = last_col,
    2835 2780
         --          (fromMaybe (srcLocCol (psRealLoc l)) last_col)
    
    2836 2781
       in POk s { pp_last_col = Nothing} offset
    
    2837 2782
     
    
    2783
    +-- See Note [GHC_CPP saved offset]
    
    2838 2784
     resetOffset :: P p ()
    
    2839 2785
     resetOffset = P $ \s -> POk s { pp_last_col = Nothing} ()
    
    2840 2786
     
    
    2787
    +{- Note [GHC_CPP saved offset]
    
    2788
    +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2789
    +
    
    2790
    +The layout processing machinery examines the offset of the previous
    
    2791
    +line when doing its calculations.
    
    2792
    +
    
    2793
    +When GHC_CPP is used, a set of CPP directives may ignore some number
    
    2794
    +of preceding lines, each of which has a different offset.
    
    2795
    +
    
    2796
    +We deal with this as follows
    
    2797
    +
    
    2798
    +- When we start skipping lines due to CPP we store the offset of the
    
    2799
    +  line before the CPP directive
    
    2800
    +- We explicitly ask for the offset using `getOffset` when doing layout
    
    2801
    +  calculations
    
    2802
    +- If there is a stored offset, we use that instead of the prior line
    
    2803
    +  offset
    
    2804
    +
    
    2805
    +-}
    
    2806
    +
    
    2841 2807
     startSkipping :: P p ()
    
    2842 2808
     startSkipping = do
    
    2843 2809
       pushLexState skipping
    
    2844 2810
       -- pushLexState (trace ("startSkipping:" ++ show skipping) skipping)
    
    2845 2811
     
    
    2846
    -stopSkipping :: P p Int
    
    2812
    +stopSkipping :: P p ()
    
    2847 2813
     stopSkipping = do
    
    2848
    -  -- popLexState
    
    2849
    -  ret <- popLexState
    
    2814
    +  _ <- popLexState
    
    2850 2815
       -- We just processed a CPP directive, which included a trailing newline.
    
    2851 2816
       -- To properly sync up, we now need to ensure that `do_bol` processing occurs.
    
    2852
    -  -- But this call does not emit a token.
    
    2853
    -  -- Maybe it should be an argument to lexToken instead?
    
    2854
    -  -- Alternatively, push the input location to the previous char.
    
    2855
    -  AI ps buf <- getInput
    
    2856
    -  last_buf_cur <- getLastBufCur
    
    2857
    -  last_loc <- getLastLoc
    
    2817
    +  -- But this call does not emit a token, so we instead
    
    2818
    +  -- change the input location to the previous char, the newline
    
    2819
    +  AI _ps buf <- getInput
    
    2858 2820
       last_tk <- getLastTk
    
    2859 2821
       case last_tk of
    
    2860 2822
         Strict.Just (L l _) -> do
    
    2861 2823
           let ps' = PsLoc (realSrcSpanEnd (psRealSpan l)) (bufSpanEnd (psBufSpan l))
    
    2862 2824
           let cur' = (cur buf) - 1
    
    2863
    -      -- let cur' = trace ("stopSkipping:(cur',ps'):" ++ show (cur'',ps')) cur''
    
    2864 2825
           setInput (AI ps' (buf { cur = cur'}))
    
    2865 2826
         _ -> return ()
    
    2866
    -  -- return $ trace ("stopSkipping: (ps, cur buf, last_loc, last_buf_cur, last_tk):" ++ show (ps, cur buf, last_loc, last_buf_cur, last_tk)) ret
    
    2867
    -  return ret
    
    2868 2827
     
    
    2869 2828
       -- old <- popLexState
    
    2870 2829
       -- return (trace ("stopSkipping:" ++ show old) old)
    
    2871 2830
     
    
    2872 2831
     
    
    2873
    -getAlrState :: P p PSavedAlrState
    
    2874
    -getAlrState = P $ \s@(PState  {loc=l}) -> POk s
    
    2875
    -  PSavedAlrState {
    
    2876
    -        -- s_warnings = warnings s,
    
    2877
    -        -- s_errors = errors s,
    
    2878
    -        -- s_lex_state = lex_state s,
    
    2879
    -        s_lex_state = lex_state s,
    
    2880
    -        s_context = context s,
    
    2881
    -        s_alr_pending_implicit_tokens = alr_pending_implicit_tokens s,
    
    2882
    -        s_alr_next_token = alr_next_token s,
    
    2883
    -        s_alr_last_loc = alr_last_loc s,
    
    2884
    -        s_alr_context = alr_context s,
    
    2885
    -        s_alr_expecting_ocurly = alr_expecting_ocurly s,
    
    2886
    -        s_alr_justClosedExplicitLetBlock = alr_justClosedExplicitLetBlock s,
    
    2887
    -        s_last_col = srcLocCol (psRealLoc l)
    
    2888
    -    }
    
    2889
    -
    
    2890
    -setAlrState :: PSavedAlrState -> P p ()
    
    2891
    -setAlrState ss = P $ \s -> POk s {
    
    2892
    -        -- errors = s_errors ss,
    
    2893
    -        -- warnings = s_warnings ss,
    
    2894
    -        lex_state = s_lex_state ss,
    
    2895
    -        context = s_context ss,
    
    2896
    -        alr_pending_implicit_tokens = s_alr_pending_implicit_tokens ss,
    
    2897
    -        alr_next_token = s_alr_next_token ss,
    
    2898
    -        alr_last_loc = s_alr_last_loc ss,
    
    2899
    -        alr_context = s_alr_context ss,
    
    2900
    -        alr_expecting_ocurly = s_alr_expecting_ocurly ss,
    
    2901
    -        alr_justClosedExplicitLetBlock = s_alr_justClosedExplicitLetBlock ss,
    
    2902
    -        pp_last_col = Just (s_last_col ss)
    
    2903
    -    } ()
    
    2904
    -
    
    2905
    -
    
    2906 2832
     
    
    2907 2833
     {-# INLINE alexGetChar' #-}
    
    2908 2834
     -- This version does not squash unicode characters, it is used when
    
    ... ... @@ -3199,6 +3125,7 @@ disableHaddock opts = upd_bitmap (xunset HaddockBit)
    3199 3125
       where
    
    3200 3126
         upd_bitmap f = opts { pExtsBitmap = f (pExtsBitmap opts) }
    
    3201 3127
     
    
    3128
    +-- TODO:AZ check which of these are actually needed,
    
    3202 3129
     enableGhcCpp :: ParserOpts -> ParserOpts
    
    3203 3130
     enableGhcCpp = enableExtBit GhcCppBit
    
    3204 3131
     
    
    ... ... @@ -3881,8 +3808,6 @@ warn_unknown_prag prags span buf len buf2 = do
    3881 3808
     %************************************************************************
    
    3882 3809
     -}
    
    3883 3810
     
    
    3884
    --- TODO:AZ: we should have only mkParensEpToks. Delete mkParensEpAnn, mkParensLocs
    
    3885
    -
    
    3886 3811
     -- |Given a 'RealSrcSpan' that surrounds a 'HsPar' or 'HsParTy', generate
    
    3887 3812
     -- 'EpToken' values for the opening and closing bordering on the start
    
    3888 3813
     -- and end of the span
    

  • compiler/GHC/Parser/PreProcess.hs
    ... ... @@ -14,8 +14,8 @@ module GHC.Parser.PreProcess (
    14 14
     ) where
    
    15 15
     
    
    16 16
     import Data.List (intercalate, sortBy)
    
    17
    -import Data.Maybe (fromMaybe, listToMaybe)
    
    18 17
     import Data.Map qualified as Map
    
    18
    +import Data.Maybe (fromMaybe, listToMaybe)
    
    19 19
     import Debug.Trace (trace)
    
    20 20
     import GHC.Data.FastString
    
    21 21
     import GHC.Data.Strict qualified as Strict
    
    ... ... @@ -23,6 +23,7 @@ import GHC.Data.StringBuffer
    23 23
     import GHC.Driver.DynFlags (DynFlags, xopt)
    
    24 24
     import GHC.LanguageExtensions qualified as LangExt
    
    25 25
     import GHC.Parser.Errors.Ppr ()
    
    26
    +import GHC.Parser.Errors.Types (PsMessage (PsErrGhcCpp))
    
    26 27
     import GHC.Parser.Lexer (P (..), PState (..), ParseResult (..), Token (..))
    
    27 28
     import GHC.Parser.Lexer qualified as Lexer
    
    28 29
     import GHC.Parser.PreProcess.Macro
    
    ... ... @@ -34,7 +35,6 @@ import GHC.Types.SrcLoc
    34 35
     import GHC.Utils.Error
    
    35 36
     import GHC.Utils.Outputable (text)
    
    36 37
     import GHC.Utils.Panic.Plain (panic)
    
    37
    -import GHC.Parser.Errors.Types (PsMessage(PsErrGhcCpp))
    
    38 38
     
    
    39 39
     -- ---------------------------------------------------------------------
    
    40 40
     
    
    ... ... @@ -42,9 +42,10 @@ dumpGhcCpp :: DynFlags -> PState PpState -> SDoc
    42 42
     dumpGhcCpp dflags pst = output
    
    43 43
       where
    
    44 44
         ghc_cpp_enabled = xopt LangExt.GhcCpp dflags
    
    45
    -    output = if ghc_cpp_enabled
    
    46
    -                then text $ sepa ++ defines ++ sepa ++ final ++ sepa
    
    47
    -                else text "GHC_CPP not enabled"
    
    45
    +    output =
    
    46
    +        if ghc_cpp_enabled
    
    47
    +            then text $ sepa ++ defines ++ sepa ++ final ++ sepa
    
    48
    +            else text "GHC_CPP not enabled"
    
    48 49
         -- Note: pst is the state /before/ the parser runs, so we can use it to lex.
    
    49 50
         (pst_final, bare_toks) = lexAll pst
    
    50 51
         comments = reverse (Lexer.comment_q pst_final)
    
    ... ... @@ -76,6 +77,7 @@ renderCombinedToks toks = showCppTokenStream toks
    76 77
     -- ---------------------------------------------------------------------
    
    77 78
     -- addSourceToTokens copied here to unbreak an import loop.
    
    78 79
     -- It should probably move somewhere else
    
    80
    +-- TODO: We should be able to do away with this once #26095 is done
    
    79 81
     
    
    80 82
     {- | Given a source location and a StringBuffer corresponding to this
    
    81 83
     location, return a rich token stream with the source associated to the
    
    ... ... @@ -105,7 +107,8 @@ addSourceToTokens loc0 buf0 (t@(L sp _) : ts) =
    105 107
     
    
    106 108
     -- ---------------------------------------------------------------------
    
    107 109
     
    
    108
    --- Tweaked from showRichTokenStream
    
    110
    +-- Tweaked from showRichTokenStream, to add markers per line if it is
    
    111
    +-- currently active or not
    
    109 112
     showCppTokenStream :: [(Located Token, String)] -> String
    
    110 113
     showCppTokenStream ts0 = go startLoc ts0 ""
    
    111 114
       where
    
    ... ... @@ -196,7 +199,7 @@ ppLexer queueComments cont =
    196 199
                         ppLexer queueComments cont
    
    197 200
                  in
    
    198 201
                     case tk of
    
    199
    -                -- case (trace ("M.ppLexer:tk=" ++ show (unLoc tk)) tk) of
    
    202
    +                    -- case (trace ("M.ppLexer:tk=" ++ show (unLoc tk)) tk) of
    
    200 203
                         L _ ITeof -> do
    
    201 204
                             mInp <- popIncludeLoc
    
    202 205
                             case mInp of
    
    ... ... @@ -219,13 +222,11 @@ ppLexer queueComments cont =
    219 222
                                             case mdump of
    
    220 223
                                                 Just dump ->
    
    221 224
                                                     -- We have a dump of the state, put it into an ignored token
    
    225
    +                                                -- AZ: TODO: is this actually useful?
    
    222 226
                                                     contIgnoreTok (L l (ITcpp continuation (appendFS s (fsLit dump)) sp))
    
    223 227
                                                 Nothing -> contIgnoreTok tk
    
    224 228
                                 else contInner tk
    
    225 229
                         L _ (ITcppIgnored _ _) -> contIgnoreTok tk
    
    226
    -                    L _ (ITline_prag _) -> do
    
    227
    -                        setInLinePragma True
    
    228
    -                        contIgnoreTok tk
    
    229 230
                         _ -> do
    
    230 231
                             state <- getCppState
    
    231 232
                             inLinePragma <- getInLinePragma
    
    ... ... @@ -253,7 +254,7 @@ processCppToks fs = do
    253 254
         -- Combine any prior continuation tokens
    
    254 255
         cs <- popContinuation
    
    255 256
         let loc = combineLocs fs (fromMaybe fs (listToMaybe cs))
    
    256
    -    processCpp  loc (concat $ reverse $ map get (fs:cs))
    
    257
    +    processCpp loc (concat $ reverse $ map get (fs : cs))
    
    257 258
     
    
    258 259
     processCpp :: SrcSpan -> String -> PP (Maybe String)
    
    259 260
     processCpp loc s = do
    
    ... ... @@ -262,13 +263,11 @@ processCpp loc s = do
    262 263
             then return (Just "\ndumped state\n")
    
    263 264
             else do
    
    264 265
                 case directive of
    
    265
    -                Left err ->  Lexer.addError $ mkPlainErrorMsgEnvelope loc $ PsErrGhcCpp (text err)
    
    266
    +                Left err -> Lexer.addError $ mkPlainErrorMsgEnvelope loc $ PsErrGhcCpp (text err)
    
    266 267
                     Right (CppInclude filename) -> do
    
    267 268
                         ppInclude filename
    
    268
    -                Right (CppDefine name args def) -> do
    
    269
    -                    ppDefine (MacroName name args) def
    
    270
    -                Right (CppUndef name) -> do
    
    271
    -                    ppUndef name
    
    269
    +                Right (CppDefine name args def) -> ppDefine (MacroName name args) def
    
    270
    +                Right (CppUndef name) -> ppUndef name
    
    272 271
                     Right (CppIf cond) -> do
    
    273 272
                         val <- cppCond loc cond
    
    274 273
                         ar <- pushAccepting val
    

  • compiler/GHC/Parser/PreProcess/Macro.hs
    ... ... @@ -37,12 +37,15 @@ import Data.Map qualified as Map
    37 37
     import Data.Maybe
    
    38 38
     
    
    39 39
     import Data.Semigroup qualified as S
    
    40
    +import GHC.Driver.Errors.Types (PsMessage)
    
    41
    +import GHC.Parser.Lexer qualified as Lexer
    
    40 42
     import GHC.Parser.PreProcess.Eval
    
    41 43
     import GHC.Parser.PreProcess.ParsePP
    
    42 44
     import GHC.Parser.PreProcess.Parser qualified as Parser
    
    43 45
     import GHC.Parser.PreProcess.ParserM
    
    44 46
     import GHC.Parser.PreProcess.State
    
    45 47
     import GHC.Prelude
    
    48
    +import GHC.Types.Error (MsgEnvelope)
    
    46 49
     import GHC.Types.SrcLoc
    
    47 50
     import GHC.Utils.Outputable
    
    48 51
     import GHC.Utils.Panic (panic)
    
    ... ... @@ -54,58 +57,84 @@ cppCond :: SrcSpan -> String -> PP Bool
    54 57
     cppCond loc str = do
    
    55 58
         s <- getPpState
    
    56 59
         expanded <- expand loc (pp_defines s) str
    
    57
    -    v <- case Parser.parseExpr expanded of
    
    60
    +    case expanded of
    
    58 61
             Left err -> do
    
    59
    -            addGhcCPPError
    
    60
    -                loc
    
    61
    -                ( hang
    
    62
    -                    (text "Error evaluating CPP condition:")
    
    63
    -                    2
    
    64
    -                    (text err <+> text "of" $+$ text expanded)
    
    65
    -                )
    
    66
    -            return 0
    
    67
    -        Right tree -> return (eval tree)
    
    68
    -    return (toBool v)
    
    62
    +            Lexer.addError err
    
    63
    +            return False
    
    64
    +        Right expanded -> do
    
    65
    +            v <- case Parser.parseExpr expanded of
    
    66
    +                Left err -> do
    
    67
    +                    let detail =
    
    68
    +                            if str == expanded || expanded == ""
    
    69
    +                                then
    
    70
    +                                    [ text str
    
    71
    +                                    ]
    
    72
    +                                else
    
    73
    +                                    [ text expanded
    
    74
    +                                    , text "expanded from:"
    
    75
    +                                    , text str
    
    76
    +                                    ]
    
    77
    +                    addGhcCPPError
    
    78
    +                        loc
    
    79
    +                        ( hang
    
    80
    +                            (text "Error evaluating CPP condition:")
    
    81
    +                            2
    
    82
    +                            ( text err
    
    83
    +                                <+> text "of"
    
    84
    +                                $+$ vcat detail
    
    85
    +                            )
    
    86
    +                        )
    
    87
    +                    return 0
    
    88
    +                Right tree -> return (eval tree)
    
    89
    +            return (toBool v)
    
    69 90
     
    
    70 91
     -- ---------------------------------------------------------------------
    
    71 92
     
    
    72
    -expand :: SrcSpan -> MacroDefines -> String -> PP String
    
    93
    +expand :: SrcSpan -> MacroDefines -> String -> PP (Either (MsgEnvelope PsMessage) String)
    
    73 94
     expand loc s str = do
    
    74
    -    toks <- case cppLex False str of
    
    95
    +    case cppLex False str of
    
    75 96
             Left err -> do
    
    76
    -            addGhcCPPError
    
    77
    -                loc
    
    78
    -                ( hang
    
    79
    -                    (text "Error evaluating CPP condition:")
    
    80
    -                    2
    
    81
    -                    (text err <+> text "of" $+$ text str)
    
    97
    +            return
    
    98
    +                ( Left $
    
    99
    +                    mkGhcCPPError
    
    100
    +                        loc
    
    101
    +                        ( hang
    
    102
    +                            (text "Error evaluating CPP condition:")
    
    103
    +                            2
    
    104
    +                            (text err <+> text "of" $+$ text str)
    
    105
    +                        )
    
    82 106
                     )
    
    83
    -            return []
    
    84
    -        Right tks -> return tks
    
    85
    -    expandedToks <- expandToks loc maxExpansions s toks
    
    86
    -    return $ combineToks $ map t_str expandedToks
    
    107
    +        Right tks -> do
    
    108
    +            expandedToks <- expandToks loc maxExpansions s tks
    
    109
    +            case expandedToks of
    
    110
    +                Left err -> return (Left err)
    
    111
    +                Right toks -> return $ Right $ combineToks $ map t_str toks
    
    87 112
     
    
    88 113
     maxExpansions :: Int
    
    89 114
     maxExpansions = 15
    
    90 115
     
    
    91
    -expandToks :: SrcSpan -> Int -> MacroDefines -> [Token] -> PP [Token]
    
    116
    +expandToks :: SrcSpan -> Int -> MacroDefines -> [Token] -> PP (Either (MsgEnvelope PsMessage) [Token])
    
    92 117
     expandToks loc 0 _ ts = do
    
    93
    -    addGhcCPPError
    
    94
    -        loc
    
    95
    -        ( hang
    
    96
    -            (text "CPP macro expansion limit hit:")
    
    97
    -            2
    
    98
    -            (text (combineToks $ map t_str ts))
    
    99
    -        )
    
    100
    -    return ts
    
    118
    +    return $
    
    119
    +        Left $
    
    120
    +            mkGhcCPPError
    
    121
    +                loc
    
    122
    +                ( hang
    
    123
    +                    (text "CPP macro expansion limit hit:")
    
    124
    +                    2
    
    125
    +                    (text (combineToks $ map t_str ts))
    
    126
    +                )
    
    101 127
     expandToks loc cnt s ts = do
    
    102
    -    (!expansionDone, !r) <- doExpandToks loc False s ts
    
    103
    -    if expansionDone
    
    104
    -        then expandToks loc (cnt - 1) s r
    
    105
    -        else return r
    
    106
    -
    
    107
    -doExpandToks :: SrcSpan -> Bool -> MacroDefines -> [Token] -> PP (Bool, [Token])
    
    108
    -doExpandToks _loc ed _ [] = return (ed, [])
    
    128
    +    expansion <- doExpandToks loc False s ts
    
    129
    +    case expansion of
    
    130
    +        Left err -> return (Left err)
    
    131
    +        Right (!expansionDone, !r) ->
    
    132
    +            if expansionDone
    
    133
    +                then expandToks loc (cnt - 1) s r
    
    134
    +                else return (Right r)
    
    135
    +
    
    136
    +doExpandToks :: SrcSpan -> Bool -> MacroDefines -> [Token] -> PP (Either (MsgEnvelope PsMessage) (Bool, [Token]))
    
    137
    +doExpandToks _loc ed _ [] = return $ Right (ed, [])
    
    109 138
     doExpandToks loc ed s (TIdentifierLParen n : ts) =
    
    110 139
         -- TIdentifierLParen has no meaning here (only in a #define), so
    
    111 140
         -- restore it to its constituent tokens
    
    ... ... @@ -116,30 +145,32 @@ doExpandToks loc _ s (TIdentifier "defined" : ts) = do
    116 145
         case expandedArgs of
    
    117 146
             (Just [[TIdentifier macro_name]], rest0) ->
    
    118 147
                 case Map.lookup macro_name s of
    
    119
    -                Nothing -> return (True, TInteger "0" : rest0)
    
    120
    -                Just _ -> return (True, TInteger "1" : rest0)
    
    148
    +                Nothing -> return $ Right (True, TInteger "0" : rest0)
    
    149
    +                Just _ -> return $ Right (True, TInteger "1" : rest0)
    
    121 150
             (Nothing, TIdentifier macro_name : ts0) ->
    
    122 151
                 case Map.lookup macro_name s of
    
    123
    -                Nothing -> return (True, TInteger "0" : ts0)
    
    124
    -                Just _ -> return (True, TInteger "1" : ts0)
    
    152
    +                Nothing -> return $ Right (True, TInteger "0" : ts0)
    
    153
    +                Just _ -> return $ Right (True, TInteger "1" : ts0)
    
    125 154
             (Nothing, _) -> do
    
    126
    -            addGhcCPPError
    
    127
    -                loc
    
    128
    -                ( hang
    
    129
    -                    (text "CPP defined: expected an identifier, got:")
    
    130
    -                    2
    
    131
    -                    (text (concatMap t_str ts))
    
    132
    -                )
    
    133
    -            return (False, [])
    
    155
    +            return $
    
    156
    +                Left $
    
    157
    +                    mkGhcCPPError
    
    158
    +                        loc
    
    159
    +                        ( hang
    
    160
    +                            (text "CPP defined: expected an identifier, got:")
    
    161
    +                            2
    
    162
    +                            (text (concatMap t_str ts))
    
    163
    +                        )
    
    134 164
             (Just args, _) -> do
    
    135
    -            addGhcCPPError
    
    136
    -                loc
    
    137
    -                ( hang
    
    138
    -                    (text "CPP defined: expected a single arg, got:")
    
    139
    -                    2
    
    140
    -                    (text (intercalate "," (map (concatMap t_str) args)))
    
    141
    -                )
    
    142
    -            return (False, [])
    
    165
    +            return $
    
    166
    +                Left $
    
    167
    +                    mkGhcCPPError
    
    168
    +                        loc
    
    169
    +                        ( hang
    
    170
    +                            (text "CPP defined: expected a single arg, got:")
    
    171
    +                            2
    
    172
    +                            (text (intercalate "," (map (concatMap t_str) args)))
    
    173
    +                        )
    
    143 174
     doExpandToks loc ed s (TIdentifier n : ts) = do
    
    144 175
         (args, rest0) <- getExpandArgs loc ts
    
    145 176
         let
    
    ... ... @@ -152,11 +183,15 @@ doExpandToks loc ed s (TIdentifier n : ts) = do
    152 183
                     (ed0, r, rest1) = case m_args of
    
    153 184
                         Nothing -> (True, rhs, ts)
    
    154 185
                         Just _ -> (True, replace_args args m_args rhs, rest0)
    
    155
    -    (ed'', rest) <- doExpandToks loc ed' s ts'
    
    156
    -    return (ed'', expanded ++ rest)
    
    186
    +    expansion <- doExpandToks loc ed' s ts'
    
    187
    +    case expansion of
    
    188
    +        Left err -> return $ Left err
    
    189
    +        Right (ed'', rest) -> return $ Right (ed'', expanded ++ rest)
    
    157 190
     doExpandToks loc ed s (t : ts) = do
    
    158
    -    (ed', r) <- doExpandToks loc ed s ts
    
    159
    -    return (ed', t : r)
    
    191
    +    expansion <- doExpandToks loc ed s ts
    
    192
    +    case expansion of
    
    193
    +        Left err -> return (Left err)
    
    194
    +        Right (ed', r) -> return $ Right (ed', t : r)
    
    160 195
     
    
    161 196
     {-
    
    162 197
     Note: ['defined' unary operator]
    

  • compiler/GHC/Parser/PreProcess/State.hs
    ... ... @@ -32,6 +32,7 @@ module GHC.Parser.PreProcess.State (
    32 32
         ghcCppEnabled,
    
    33 33
         setInLinePragma,
    
    34 34
         getInLinePragma,
    
    35
    +    mkGhcCPPError,
    
    35 36
         addGhcCPPError,
    
    36 37
     ) where
    
    37 38
     
    
    ... ... @@ -71,7 +72,6 @@ initPpState =
    71 72
             , pp_continuation = []
    
    72 73
             , pp_defines = Map.empty
    
    73 74
             , pp_scope = (PpScope True PpNoGroup) :| []
    
    74
    -        , pp_alr_state = Nothing
    
    75 75
             , pp_in_line_pragma = False
    
    76 76
             }
    
    77 77
     
    
    ... ... @@ -81,7 +81,6 @@ data PpState = PpState
    81 81
         , pp_continuation :: ![Located Lexer.Token]
    
    82 82
         , pp_defines :: !MacroDefines
    
    83 83
         , pp_scope :: !(NonEmpty PpScope)
    
    84
    -    , pp_alr_state :: Maybe Lexer.PSavedAlrState
    
    85 84
         , pp_in_line_pragma :: !Bool
    
    86 85
         }
    
    87 86
     
    
    ... ... @@ -416,6 +415,8 @@ insertMacroDef (MacroName name args) def md =
    416 415
     
    
    417 416
     -- ---------------------------------------------------------------------
    
    418 417
     
    
    418
    +mkGhcCPPError :: SrcSpan -> SDoc -> MsgEnvelope PsMessage
    
    419
    +mkGhcCPPError loc err = mkPlainErrorMsgEnvelope loc $ PsErrGhcCpp err
    
    420
    +
    
    419 421
     addGhcCPPError :: SrcSpan -> SDoc -> P p ()
    
    420
    -addGhcCPPError loc err =
    
    421
    -    Lexer.addError $ mkPlainErrorMsgEnvelope loc $ PsErrGhcCpp err
    422
    +addGhcCPPError loc err = Lexer.addError $ mkGhcCPPError loc err

  • testsuite/tests/ghc-cpp/GhcCpp02.stderr
    ... ... @@ -6,28 +6,15 @@ GhcCpp02.hs:12:1: error: [GHC-93098]
    6 6
         Error evaluating CPP condition:
    
    7 7
           Parse error at line 1, column 23 of
    
    8 8
           2 + NONEXISTENT_MACRO ( 4 )
    
    9
    -
    
    10
    -GhcCpp02.hs:17:1: error: [GHC-93098]
    
    11
    -    Error evaluating CPP condition:
    
    12
    -      Parse error at line 1, column 4 of
    
    13
    -      FOO( 3 )
    
    9
    +      expanded from:
    
    10
    +      EXISTENT_MACRO( 4 )
    
    14 11
     
    
    15 12
     GhcCpp02.hs:17:1: error: [GHC-93098]
    
    16 13
         CPP macro expansion limit hit: FOO( 3 )
    
    17 14
     
    
    18
    -GhcCpp02.hs:21:1: error: [GHC-93098]
    
    19
    -    Error evaluating CPP condition:
    
    20
    -      Parse error at line 1, column 0 of
    
    21
    -      
    
    22
    -
    
    23 15
     GhcCpp02.hs:21:1: error: [GHC-93098]
    
    24 16
         CPP defined: expected an identifier, got: 34
    
    25 17
     
    
    26
    -GhcCpp02.hs:24:1: error: [GHC-93098]
    
    27
    -    Error evaluating CPP condition:
    
    28
    -      Parse error at line 1, column 0 of
    
    29
    -      
    
    30
    -
    
    31 18
     GhcCpp02.hs:24:1: error: [GHC-93098]
    
    32 19
         CPP defined: expected a single arg, got: A,B
    
    33 20
     

  • utils/check-cpp/PreProcess.hs
    ... ... @@ -329,15 +329,8 @@ processCpp loc s = do
    329 329
     acceptStateChange :: AcceptingResult -> PP ()
    
    330 330
     acceptStateChange ArNoChange = return ()
    
    331 331
     acceptStateChange ArNowIgnoring = do
    
    332
    -    -- alr <- Lexer.getAlrState
    
    333
    -    -- s <- getPpState
    
    334
    -    -- let s = trace ("acceptStateChange:ArNowIgnoring") s'
    
    335
    -    -- setPpState (s { pp_alr_state = Just alr})
    
    336 332
         Lexer.startSkipping
    
    337 333
     acceptStateChange ArNowAccepting = do
    
    338
    -    -- s <- getPpState
    
    339
    -    -- let s = trace ("acceptStateChange:ArNowAccepting") s'
    
    340
    -    -- mapM_ Lexer.setAlrState (pp_alr_state s)
    
    341 334
         _ <- Lexer.stopSkipping
    
    342 335
         return ()
    
    343 336