Commit b779271a authored by Simon Marlow's avatar Simon Marlow

Fixes to via-C prototype generation (FIX BUILD on Windows)

  
Previously we declared all external labels with type StgWord[],
because the same label might be used at different types in the same
file, e.g. if there are multiple foreign import declarations for the
same function.  However, we have to declare called functions with the
right type on Windows, because this is the only way to make the
compiler add the appropriate '@n' suffix for stdcall functions.

Related to this is the reason we were getting mangler complaints
(epilogue mangling) when compiling the RTS with -fvia-C.  The function
barf() doesn't return, but we had lost that information by declaring
our own prototypes, and so gcc was generating extra code after the
call to barf().

For more details see
http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/PprC
parent 6f12fb75
...@@ -203,25 +203,44 @@ pprStmt stmt = case stmt of ...@@ -203,25 +203,44 @@ pprStmt stmt = case stmt of
where where
rep = cmmExprRep src rep = cmmExprRep src
CmmCall (CmmCallee fn cconv) results args safety _ret -> CmmCall (CmmCallee fn cconv) results args safety ret ->
maybe_proto $$ maybe_proto $$
pprCall ppr_fn cconv results args safety pprCall ppr_fn cconv results args safety
where where
ppr_fn = parens (cCast (pprCFunType (char '*') cconv results args) fn) cast_fn = parens (cCast (pprCFunType (char '*') cconv results args) fn)
real_fun_proto lbl = char ';' <>
pprCFunType (pprCLabel lbl) cconv results args <>
noreturn_attr <> semi
data_proto lbl = ptext (sLit ";EI_(") <>
pprCLabel lbl <> char ')' <> semi
noreturn_attr = case ret of
CmmNeverReturns -> text "__attribute__ ((noreturn))"
CmmMayReturn -> empty
-- See wiki:Commentary/Compiler/Backends/PprC#Prototypes -- See wiki:Commentary/Compiler/Backends/PprC#Prototypes
maybe_proto = (maybe_proto, ppr_fn) =
case fn of case fn of
CmmLit (CmmLabel lbl) | not (isMathFun lbl) -> CmmLit (CmmLabel lbl)
ptext (sLit ";EI_(") <+> pprCLabel lbl <> char ')' <> semi | StdCallConv <- cconv -> (real_fun_proto lbl, pprCLabel lbl)
-- we declare all called functions as data labels, -- stdcall functions must be declared with
-- and then cast them to the right type when calling. -- a function type, otherwise the C compiler
-- This is because the label might already have a -- doesn't add the @n suffix to the label. We
-- declaration as a data label in the same file, -- can't add the @n suffix ourselves, because
-- e.g. Foreign.Marshal.Alloc declares 'free' as -- it isn't valid C.
-- both a data label and a function label. | CmmNeverReturns <- ret -> (real_fun_proto lbl, pprCLabel lbl)
| not (isMathFun lbl) -> (data_proto lbl, cast_fn)
-- we declare all other called functions as
-- data labels, and then cast them to the
-- right type when calling. This is because
-- the label might already have a declaration
-- as a data label in the same file,
-- e.g. Foreign.Marshal.Alloc declares 'free'
-- as both a data label and a function label.
_ -> _ ->
empty {- no proto -} (empty {- no proto -}, cast_fn)
-- for a dynamic call, no declaration is necessary. -- for a dynamic call, no declaration is necessary.
CmmCall (CmmPrim op) results args safety _ret -> CmmCall (CmmPrim op) results args safety _ret ->
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment