172
170
end, Predef, Forms),
173
171
St#expand{defined=ordsets:from_list(Fs)}.
176
{[{attribute,Line,Name,Val} || {Name,Line,Val} <- St#expand.attributes],St}.
173
module_attrs(#expand{attributes=Attributes}=St) ->
174
Attrs = [{attribute,Line,Name,Val} || {Name,Line,Val} <- Attributes],
175
Callbacks = [Callback || {_,_,callback,_}=Callback <- Attrs],
176
{Attrs,St#expand{callbacks=Callbacks}}.
178
178
module_predef_funcs(St) ->
179
{Mpf1,St1}=module_predef_func_beh_info(St),
180
{Mpf2,St2}=module_predef_funcs_mod_info(St1),
183
module_predef_func_beh_info(#expand{callbacks=[]}=St) ->
185
module_predef_func_beh_info(#expand{callbacks=Callbacks,defined=Defined,
186
exports=Exports}=St) ->
187
PreDef=[{behaviour_info,1}],
189
{[gen_beh_info(Callbacks)],
190
St#expand{defined=union(from_list(PreDef), Defined),
191
exports=union(from_list(PreExp), Exports)}}.
193
gen_beh_info(Callbacks) ->
194
List = make_list(Callbacks),
195
{function,0,behaviour_info,1,
196
[{clause,0,[{atom,0,callbacks}],[],
199
make_list([]) -> {nil,0};
200
make_list([{_,_,_,[{{Name,Arity},_}]}|Rest]) ->
207
module_predef_funcs_mod_info(St) ->
179
208
PreDef = [{module_info,0},{module_info,1}],
181
210
{[{function,0,module_info,0,
223
252
St#expand{exports=union(from_list(Es), St#expand.exports)};
224
253
attribute(import, Is, _L, St) ->
226
attribute(compile, C, _L, St) when is_list(C) ->
227
St#expand{compile=St#expand.compile ++ C};
228
attribute(compile, C, _L, St) ->
229
St#expand{compile=St#expand.compile ++ [C]};
255
attribute(compile, _C, _L, St) ->
230
257
attribute(Name, Val, Line, St) when is_list(Val) ->
231
258
St#expand{attributes=St#expand.attributes ++ [{Name,Line,Val}]};
232
259
attribute(Name, Val, Line, St) ->
508
535
%% Transform an "explicit" fun {'fun', Line, {clauses, Cs}} into an
509
536
%% extended form {'fun', Line, {clauses, Cs}, Info}, unless it is the
510
537
%% name of a BIF (erl_lint has checked that it is not an import).
511
%% Process the body sequence directly to get the new and used variables.
512
538
%% "Implicit" funs {'fun', Line, {function, F, A}} are not changed.
514
540
fun_tq(Lf, {function,F,A}=Function, St0) ->
515
{As,St1} = new_vars(A, Lf, St0),
516
Cs = [{clause,Lf,As,[],[{call,Lf,{atom,Lf,F},As}]}],
517
541
case erl_internal:bif(F, A) of
543
{As,St1} = new_vars(A, Lf, St0),
544
Cs = [{clause,Lf,As,[],[{call,Lf,{atom,Lf,F},As}]}],
519
545
fun_tq(Lf, {clauses,Cs}, St1);
521
Index = St0#expand.fun_index,
522
Uniq = erlang:hash(Cs, (1 bsl 27)-1),
523
{Fname,St2} = new_fun_name(St1),
524
{{'fun',Lf,Function,{Index,Uniq,Fname}},
525
St2#expand{fun_index=Index+1}}
547
{Fname,St1} = new_fun_name(St0),
549
{{'fun',Lf,Function,{Index,Uniq,Fname}},St1}
527
fun_tq(L, {function,M,F,A}, St) ->
528
{{call,L,{remote,L,{atom,L,erlang},{atom,L,make_fun}},
529
[{atom,L,M},{atom,L,F},{integer,L,A}]},St};
551
fun_tq(L, {function,M,F,A}, St) when is_atom(M), is_atom(F), is_integer(A) ->
552
%% This is the old format for external funs, generated by a pre-R15
553
%% compiler. That means that a tool, such as the debugger or xref,
554
%% directly invoked this module with the abstract code from a
555
%% pre-R15 BEAM file. Be helpful, and translate it to the new format.
556
fun_tq(L, {function,{atom,L,M},{atom,L,F},{integer,L,A}}, St);
557
fun_tq(Lf, {function,_,_,_}=ExtFun, St) ->
558
{{'fun',Lf,ExtFun},St};
530
559
fun_tq(Lf, {clauses,Cs0}, St0) ->
531
Uniq = erlang:hash(Cs0, (1 bsl 27)-1),
532
560
{Cs1,St1} = fun_clauses(Cs0, St0),
533
Index = St1#expand.fun_index,
534
561
{Fname,St2} = new_fun_name(St1),
535
{{'fun',Lf,{clauses,Cs1},{Index,Uniq,Fname}},
536
St2#expand{fun_index=Index+1}}.
562
%% Set dummy values for Index and Uniq -- the real values will
563
%% be assigned by beam_asm.
565
{{'fun',Lf,{clauses,Cs1},{Index,Uniq,Fname}},St2}.
538
567
fun_clauses([{clause,L,H0,G0,B0}|Cs0], St0) ->
539
568
{H,St1} = head(H0, St0),