aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/Makefile69
-rw-r--r--lib/compiler/src/beam_asm.erl2
-rw-r--r--lib/compiler/src/beam_bool.erl27
-rw-r--r--lib/compiler/src/beam_validator.erl16
-rw-r--r--lib/compiler/src/compile.erl113
-rw-r--r--lib/compiler/src/sys_expand_pmod.erl30
-rw-r--r--lib/compiler/src/sys_pre_expand.erl60
-rw-r--r--lib/compiler/src/v3_core.erl14
8 files changed, 187 insertions, 144 deletions
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index fde2b1a655..70ddd54145 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -45,46 +45,46 @@ RELSYSDIR = $(RELEASE_PATH)/lib/compiler-$(VSN)
# Target Specs
# ----------------------------------------------------
MODULES = \
- compile \
- sys_pre_attributes \
- sys_pre_expand \
- sys_expand_pmod \
- v3_core \
- sys_core_fold \
- sys_core_inline \
- sys_core_dsetel \
- core_lib \
- core_scan \
- core_parse \
- core_lint \
- core_pp \
- v3_kernel \
- v3_kernel_pp \
- v3_life \
- v3_codegen \
+ beam_asm \
beam_block \
beam_bool \
- beam_dead \
- beam_jump \
- beam_type \
- beam_clean \
- beam_peep \
beam_bsm \
- beam_trim \
+ beam_clean \
+ beam_dead \
+ beam_dict \
+ beam_disasm \
beam_flatten \
+ beam_jump \
beam_listing \
- beam_asm \
- beam_dict \
beam_opcodes \
- beam_disasm \
+ beam_peep \
+ beam_trim \
+ beam_type \
beam_utils \
beam_validator \
- erl_bifs \
cerl \
cerl_clauses \
cerl_inline \
cerl_trees \
- rec_env
+ compile \
+ core_lib \
+ core_lint \
+ core_parse \
+ core_pp \
+ core_scan \
+ erl_bifs \
+ rec_env \
+ sys_core_dsetel \
+ sys_core_fold \
+ sys_core_inline \
+ sys_expand_pmod \
+ sys_pre_attributes \
+ sys_pre_expand \
+ v3_codegen \
+ v3_core \
+ v3_kernel \
+ v3_kernel_pp \
+ v3_life
BEAM_H = $(wildcard ../priv/beam_h/*.h)
@@ -114,6 +114,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# FLAGS
# ----------------------------------------------------
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
ERL_COMPILE_FLAGS += +inline +warn_unused_import -I../../stdlib/include -I$(EGEN) -W
# ----------------------------------------------------
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index 90d25d87b2..497c4fa07b 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -150,7 +150,7 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) ->
%% Create IFF chunk.
Chunks = case member(slim, Opts) of
- true -> [Essentials,AttrChunk,CompileChunk,AbstChunk];
+ true -> [Essentials,AttrChunk,AbstChunk];
false -> [Essentials,LocChunk,AttrChunk,CompileChunk,AbstChunk]
end,
build_form(<<"BEAM">>, Chunks).
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index d8c201a194..dcc6ad4c7c 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -123,6 +123,12 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
throw:mixed ->
failed;
+ %% There was a reference to a boolean expression
+ %% from inside a protected block (try/catch), to
+ %% a boolean expression outside.
+ throw:protected_barrier ->
+ failed;
+
%% The 'xor' operator was used. We currently don't
%% find it worthwile to translate 'xor' operators
%% (the code would be clumsy).
@@ -167,7 +173,7 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
%% whether the optimized code is guaranteed to work in the same
%% way as the original code.
%%
-%% Throws an exception if the optmization is not safe.
+%% Throw an exception if the optimization is not safe.
%%
ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) ->
%% Here are the conditions that must be true for the
@@ -184,10 +190,10 @@ ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) ->
%% by the code that follows.
%%
%% 3. Any register that is assigned a value in the optimized
- %% code must be UNUSED or KILLED in the following code.
- %% (Possible future improvement: Registers that are known
- %% to be assigned the SAME value in the original and optimized
- %% code don't need to be unused in the following code.)
+ %% code must be UNUSED or KILLED in the following code
+ %% (because the register might be assigned the wrong value,
+ %% and even if the value is right it might no longer be
+ %% assigned on *all* paths leading to its use).
InitInPreceeding = initialized_regs(PreceedingCode),
@@ -304,6 +310,8 @@ dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
+dst_regs([{set,[D],_,move}|Is], Acc) ->
+ dst_regs(Is, [D|Acc]);
dst_regs([_|Is], Acc) ->
dst_regs(Is, Acc);
dst_regs([], Acc) -> ordsets:from_list(Acc).
@@ -414,11 +422,10 @@ bopt_good_args([A|As], Regs) ->
bopt_good_args([], _) -> ok.
bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp ->
- case gb_trees:get(X, Regs) of
- any -> ok;
- _Other ->
- %%io:format("not any: ~p: ~p\n", [X,_Other]),
- throw(mixed)
+ case gb_trees:lookup(X, Regs) of
+ {value,any} -> ok;
+ {value,_} -> throw(mixed);
+ none -> throw(protected_barrier)
end;
bopt_good_arg(_, _) -> ok.
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 08ba9c3ee4..1fd61831e0 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(beam_validator).
@@ -604,9 +604,9 @@ valfun_4({gc_bif,Op,{f,Fail},Live,Src,Dst}, #vst{current=St0}=Vst0) ->
St = kill_heap_allocation(St0),
Vst1 = Vst0#vst{current=St},
verify_live(Live, Vst1),
- Vst2 = prune_x_regs(Live, Vst1),
- validate_src(Src, Vst2),
- Vst = branch_state(Fail, Vst2),
+ Vst2 = branch_state(Fail, Vst1),
+ Vst = prune_x_regs(Live, Vst2),
+ validate_src(Src, Vst),
Type = bif_type(Op, Src, Vst),
set_type_reg(Type, Dst, Vst);
valfun_4(return, #vst{current=#st{numy=none}}=Vst) ->
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index e725083a9f..b853800d73 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Purpose: Run the Erlang compiler.
@@ -187,9 +187,9 @@ format_error(no_crypto_key) ->
format_error({native, E}) ->
io_lib:fwrite("native-code compilation failed with reason: ~P.",
[E, 25]);
-format_error({native_crash, E}) ->
- io_lib:fwrite("native-code compilation crashed with reason: ~P.",
- [E, 25]);
+format_error({native_crash,E,Stk}) ->
+ io_lib:fwrite("native-code compilation crashed with reason: ~P.\n~P\n",
+ [E,25,Stk,25]);
format_error({open,E}) ->
io_lib:format("open error '~s'", [file:format_error(E)]);
format_error({epp,E}) ->
@@ -302,7 +302,7 @@ os_process_size() ->
list_to_integer(lib:nonl(Size));
_ ->
0
- end.
+ end.
run_tc({Name,Fun}, St) ->
Before0 = statistics(runtime),
@@ -318,17 +318,30 @@ run_tc({Name,Fun}, St) ->
Val.
comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) ->
- Warn = messages_per_file(Warn0),
- report_warnings(St#compile{warnings = Warn}),
- Ret1 = case member(binary, Opts) andalso not member(no_code_generation, Opts) of
- true -> [Code];
- false -> []
- end,
- Ret2 = case member(return_warnings, Opts) of
- true -> Ret1 ++ [Warn];
- false -> Ret1
- end,
- list_to_tuple([ok,Mod|Ret2]).
+ case member(warnings_as_errors, Opts) andalso length(Warn0) > 0 of
+ true ->
+ case member(report_warnings, Opts) of
+ true ->
+ io:format("~p: warnings being treated as errors\n",
+ [?MODULE]);
+ false ->
+ ok
+ end,
+ comp_ret_err(St);
+ false ->
+ Warn = messages_per_file(Warn0),
+ report_warnings(St#compile{warnings = Warn}),
+ Ret1 = case member(binary, Opts) andalso
+ not member(no_code_generation, Opts) of
+ true -> [Code];
+ false -> []
+ end,
+ Ret2 = case member(return_warnings, Opts) of
+ true -> Ret1 ++ [Warn];
+ false -> Ret1
+ end,
+ list_to_tuple([ok,Mod|Ret2])
+ end.
comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) ->
Warn = messages_per_file(Warn0),
@@ -344,18 +357,18 @@ comp_ret_err(#compile{warnings=Warn0,errors=Err0,options=Opts}=St) ->
messages_per_file(Ms) ->
T = lists:sort([{File,M} || {File,Messages} <- Ms, M <- Messages]),
PrioMs = [erl_scan, epp, erl_parse],
- {Prio0, Rest} =
+ {Prio0, Rest} =
lists:mapfoldl(fun(M, A) ->
lists:partition(fun({_,{_,Mod,_}}) -> Mod =:= M;
(_) -> false
end, A)
end, T, PrioMs),
- Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end,
+ Prio = lists:sort(fun({_,{L1,_,_}}, {_,{L2,_,_}}) -> L1 =< L2 end,
lists:append(Prio0)),
flatmap(fun mpf/1, [Prio, Rest]).
mpf(Ms) ->
- [{File,[M || {F,M} <- Ms, F =:= File]} ||
+ [{File,[M || {F,M} <- Ms, F =:= File]} ||
File <- lists:usort([F || {F,_} <- Ms])].
%% passes(form|file, [Option]) -> [{Name,PassFun}]
@@ -495,14 +508,14 @@ select_passes([List|Ps], Opts) when is_list(List) ->
select_cond(Flag, ShouldBe, Pass, Ps, Opts) ->
ShouldNotBe = not ShouldBe,
- case member(Flag, Opts) of
+ case member(Flag, Opts) of
ShouldBe -> select_passes([Pass|Ps], Opts);
ShouldNotBe -> select_passes(Ps, Opts)
end.
%% select_list_passes([Pass], Opts) -> {done,[Pass]} | {not_done,[Pass]}
%% Evaluate all conditions having to do with listings in the list of
-%% passes.
+%% passes.
select_list_passes(Ps, Opts) ->
select_list_passes_1(Ps, Opts, []).
@@ -704,7 +717,7 @@ read_beam_file(St) ->
case file:read_file(St#compile.ifile) of
{ok,Beam} ->
Infile = St#compile.ifile,
- case is_too_old(Infile) of
+ case no_native_compilation(Infile, St) of
true ->
{ok,St#compile{module=none,code=none}};
false ->
@@ -717,12 +730,15 @@ read_beam_file(St) ->
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
-is_too_old(BeamFile) ->
+no_native_compilation(BeamFile, #compile{options=Opts0}) ->
case beam_lib:chunks(BeamFile, ["CInf"]) of
{ok,{_,[{"CInf",Term0}]}} ->
Term = binary_to_term(Term0),
- Opts = proplists:get_value(options, Term, []),
- lists:member(no_new_funs, Opts);
+
+ %% Compiler options in the beam file will override
+ %% options passed to the compiler.
+ Opts = proplists:get_value(options, Term, []) ++ Opts0,
+ member(no_new_funs, Opts) orelse not is_native_enabled(Opts);
_ -> false
end.
@@ -782,7 +798,7 @@ clean_parse_transforms_1([F|Fs], Acc) ->
clean_parse_transforms_1(Fs, [F|Acc]);
clean_parse_transforms_1([], Acc) -> reverse(Acc).
-transforms(Os) -> [ M || {parse_transform,M} <- Os ].
+transforms(Os) -> [ M || {parse_transform,M} <- Os ].
transform_module(#compile{options=Opt,code=Code0}=St0) ->
%% Extract compile options from code into options field.
@@ -815,7 +831,7 @@ foldl_transform(St, [T|Ts]) ->
end;
foldl_transform(St, []) -> {ok,St}.
-get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
+get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
core_transforms(St) ->
%% The options field holds the complete list of options at this
@@ -1033,7 +1049,14 @@ beam_asm(#compile{ifile=File,code=Code0,abstract_code=Abst,options=Opts0}=St) ->
test_native(#compile{options=Opts}) ->
%% This test is done late, in case some other option has turned off native.
- member(native, Opts).
+ %% 'native' given on the command line can be overridden by
+ %% 'no_native' in the module itself.
+ is_native_enabled(Opts).
+
+is_native_enabled([native|_]) -> true;
+is_native_enabled([no_native|_]) -> false;
+is_native_enabled([_|Opts]) -> is_native_enabled(Opts);
+is_native_enabled([]) -> false.
native_compile(#compile{code=none}=St) -> {ok,St};
native_compile(St) ->
@@ -1057,25 +1080,27 @@ native_compile_1(St) ->
St#compile.core_code,
St#compile.code,
Opts) of
- {ok, {_Type,Bin} = T} when is_binary(Bin) ->
- {ok, embed_native_code(St, T)};
- {error, R} ->
+ {ok,{_Type,Bin}=T} when is_binary(Bin) ->
+ {ok,embed_native_code(St, T)};
+ {error,R} ->
case IgnoreErrors of
true ->
- Ws = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {ok, St#compile{warnings=St#compile.warnings ++ Ws}};
+ Ws = [{St#compile.ifile,[{?MODULE,{native,R}}]}],
+ {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
- Es = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {error, St#compile{errors=St#compile.errors ++ Es}}
+ Es = [{St#compile.ifile,[{?MODULE,{native,R}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
end
catch
- error:R ->
+ Class:R ->
+ Stk = erlang:get_stacktrace(),
case IgnoreErrors of
true ->
- Ws = [{St#compile.ifile,[{none,?MODULE,{native_crash,R}}]}],
- {ok, St#compile{warnings=St#compile.warnings ++ Ws}};
+ Ws = [{St#compile.ifile,
+ [{?MODULE,{native_crash,R,Stk}}]}],
+ {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
- exit(R)
+ erlang:raise(Class, R, Stk)
end
end.
@@ -1264,7 +1289,7 @@ listing(Ext, St) ->
listing(LFun, Ext, St) ->
Lfile = outfile(St#compile.base, Ext, St#compile.options),
case file:open(Lfile, [write,delayed_write]) of
- {ok,Lf} ->
+ {ok,Lf} ->
Code = restore_expanded_types(Ext, St#compile.code),
LFun(Lf, Code),
ok = file:close(Lf),
diff --git a/lib/compiler/src/sys_expand_pmod.erl b/lib/compiler/src/sys_expand_pmod.erl
index dbd5c1ec2f..4fee26f2a6 100644
--- a/lib/compiler/src/sys_expand_pmod.erl
+++ b/lib/compiler/src/sys_expand_pmod.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(sys_expand_pmod).
@@ -283,9 +283,13 @@ expr({cons,Line,H0,T0},St) ->
T1 = expr(T0,St),
{cons,Line,H1,T1};
expr({lc,Line,E0,Qs0},St) ->
- Qs1 = lc_quals(Qs0,St),
+ Qs1 = lc_bc_quals(Qs0,St),
E1 = expr(E0,St),
{lc,Line,E1,Qs1};
+expr({bc,Line,E0,Qs0},St) ->
+ Qs1 = lc_bc_quals(Qs0,St),
+ E1 = expr(E0,St),
+ {bc,Line,E1,Qs1};
expr({tuple,Line,Es0},St) ->
Es1 = expr_list(Es0,St),
{tuple,Line,Es1};
@@ -391,14 +395,18 @@ icr_clauses([C0|Cs],St) ->
[C1|icr_clauses(Cs,St)];
icr_clauses([],_St) -> [].
-lc_quals([{generate,Line,P0,E0}|Qs],St) ->
+lc_bc_quals([{generate,Line,P0,E0}|Qs],St) ->
+ E1 = expr(E0,St),
+ P1 = pattern(P0,St),
+ [{generate,Line,P1,E1}|lc_bc_quals(Qs,St)];
+lc_bc_quals([{b_generate,Line,P0,E0}|Qs],St) ->
E1 = expr(E0,St),
P1 = pattern(P0,St),
- [{generate,Line,P1,E1}|lc_quals(Qs,St)];
-lc_quals([E0|Qs],St) ->
+ [{b_generate,Line,P1,E1}|lc_bc_quals(Qs,St)];
+lc_bc_quals([E0|Qs],St) ->
E1 = expr(E0,St),
- [E1|lc_quals(Qs,St)];
-lc_quals([],_St) -> [].
+ [E1|lc_bc_quals(Qs,St)];
+lc_bc_quals([],_St) -> [].
fun_clauses([C0|Cs],St) ->
C1 = clause(C0,St),
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
index 78dd73e0a2..f80d03dfac 100644
--- a/lib/compiler/src/sys_pre_expand.erl
+++ b/lib/compiler/src/sys_pre_expand.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Purpose : Expand some source Erlang constructions. This is part of the
@@ -114,7 +114,7 @@ expand_pmod(Fs0, St0) ->
St1 = St0#expand{exports=Xs, defined=Ds},
{Fs2,St2} = add_instance(Ps, Fs1, St1),
{Fs3,St3} = ensure_new(Base, Ps0, Fs2, St2),
- {Fs3,St3#expand{attributes = [{abstract, [true]}
+ {Fs3,St3#expand{attributes = [{abstract, 0, [true]}
| St3#expand.attributes]}}
end.
@@ -173,7 +173,7 @@ define_functions(Forms, #expand{defined=Predef}=St) ->
St#expand{defined=ordsets:from_list(Fs)}.
module_attrs(St) ->
- {[{attribute,0,Name,Val} || {Name,Val} <- St#expand.attributes],St}.
+ {[{attribute,Line,Name,Val} || {Name,Line,Val} <- St#expand.attributes],St}.
module_predef_funcs(St) ->
PreDef = [{module_info,0},{module_info,1}],
@@ -197,8 +197,8 @@ module_predef_funcs(St) ->
forms([{attribute,_,file,_File}=F|Fs0], St0) ->
{Fs,St1} = forms(Fs0, St0),
{[F|Fs],St1};
-forms([{attribute,_,Name,Val}|Fs0], St0) ->
- St1 = attribute(Name, Val, St0),
+forms([{attribute,Line,Name,Val}|Fs0], St0) ->
+ St1 = attribute(Name, Val, Line, St0),
forms(Fs0, St1);
forms([{function,L,N,A,Cs}|Fs0], St0) ->
{Ff,St1} = function(L, N, A, Cs, St0),
@@ -207,30 +207,30 @@ forms([{function,L,N,A,Cs}|Fs0], St0) ->
forms([_|Fs], St) -> forms(Fs, St);
forms([], St) -> {[],St}.
-%% attribute(Attribute, Value, State) -> State'.
+%% attribute(Attribute, Value, Line, State) -> State'.
%% Process an attribute, this just affects the state.
-attribute(module, {Module, As}, St) ->
+attribute(module, {Module, As}, _L, St) ->
M = package_to_string(Module),
St#expand{module=list_to_atom(M),
- package = packages:strip_last(M),
+ package=packages:strip_last(M),
parameters=As};
-attribute(module, Module, St) ->
+attribute(module, Module, _L, St) ->
M = package_to_string(Module),
St#expand{module=list_to_atom(M),
- package = packages:strip_last(M)};
-attribute(export, Es, St) ->
+ package=packages:strip_last(M)};
+attribute(export, Es, _L, St) ->
St#expand{exports=union(from_list(Es), St#expand.exports)};
-attribute(import, Is, St) ->
+attribute(import, Is, _L, St) ->
import(Is, St);
-attribute(compile, C, St) when is_list(C) ->
+attribute(compile, C, _L, St) when is_list(C) ->
St#expand{compile=St#expand.compile ++ C};
-attribute(compile, C, St) ->
+attribute(compile, C, _L, St) ->
St#expand{compile=St#expand.compile ++ [C]};
-attribute(Name, Val, St) when is_list(Val) ->
- St#expand{attributes=St#expand.attributes ++ [{Name,Val}]};
-attribute(Name, Val, St) ->
- St#expand{attributes=St#expand.attributes ++ [{Name,[Val]}]}.
+attribute(Name, Val, Line, St) when is_list(Val) ->
+ St#expand{attributes=St#expand.attributes ++ [{Name,Line,Val}]};
+attribute(Name, Val, Line, St) ->
+ St#expand{attributes=St#expand.attributes ++ [{Name,Line,[Val]}]}.
function(L, N, A, Cs0, St0) ->
{Cs,St} = clauses(Cs0, St0#expand{func=N,arity=A,fcount=0}),
@@ -299,10 +299,10 @@ pattern({match,Line,Pat1, Pat2}, St0) ->
{TT,St2} = pattern(Pat1, St1),
{{match,Line,TT,TH},St2};
%% Compile-time pattern expressions, including unary operators.
-pattern({op,Line,Op,A}, St) ->
- {erl_eval:partial_eval({op,Line,Op,A}),St};
-pattern({op,Line,Op,L,R}, St) ->
- {erl_eval:partial_eval({op,Line,Op,L,R}),St}.
+pattern({op,_Line,_Op,_A}=Op, St) ->
+ {erl_eval:partial_eval(Op),St};
+pattern({op,_Line,_Op,_L,_R}=Op, St) ->
+ {erl_eval:partial_eval(Op),St}.
pattern_list([P0|Ps0], St0) ->
{P,St1} = pattern(P0, St0),
@@ -400,18 +400,18 @@ expr({'receive',Line,Cs0,To0,ToEs0}, St0) ->
{{'receive',Line,Cs,To,ToEs},St3};
expr({'fun',Line,Body}, St) ->
fun_tq(Line, Body, St);
-expr({call,Line,{atom,La,N},As0}, St0) ->
+expr({call,Line,{atom,La,N}=Atom,As0}, St0) ->
{As,St1} = expr_list(As0, St0),
Ar = length(As),
case erl_internal:bif(N, Ar) of
true ->
- {{call,Line,{remote,La,{atom,La,erlang},{atom,La,N}},As},St1};
+ {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1};
false ->
case imported(N, Ar, St1) of
{yes,Mod} ->
- {{call,Line,{remote,La,{atom,La,Mod},{atom,La,N}},As},St1};
+ {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1};
no ->
- {{call,Line,{atom,La,N},As},St1}
+ {{call,Line,Atom,As},St1}
end
end;
expr({call,Line,{record_field,_,_,_}=M,As0}, St0) ->
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index a39a3c538f..dfe15de4ff 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Purpose : Transform normal Erlang to Core Erlang
@@ -164,8 +164,8 @@ form({attribute,_,file,{File,_Line}}, {Fs,As,Es,Ws,_}, _Opts) ->
form({attribute,_,_,_}=F, {Fs,As,Es,Ws,File}, _Opts) ->
{Fs,[attribute(F)|As],Es,Ws,File}.
-attribute({attribute,_,Name,Val}) ->
- {#c_literal{val=Name},#c_literal{val=Val}}.
+attribute({attribute,Line,Name,Val}) ->
+ {#c_literal{val=Name, anno=[Line]}, #c_literal{val=Val, anno=[Line]}}.
function({function,_,Name,Arity,Cs0}, Es0, Ws0, File, Opts) ->
%%ok = io:fwrite("~p - ", [{Name,Arity}]),