mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-22 04:43:53 +00:00
If an enum type is exported to a foreign language, that foreign language is effectively in charge of deciding its representation, so our previous assumption that the enum fits info ceil(log2(num_alternatives)) bits is wrong. This is Mantis bug #382, which this diff fixes. The code in du_type_layout.m that does the packing is correct, but it was being given incomplete data. du_type_layout.m is invoked after pass 2 in make_hlds_passes.m, but the foreign_enum pragmas that make the packing invalid weren't being added until pass 3. The simple fix is to process those pragmas in pass 2, which requires moving the definitions of the types they apply to from pass 2 to pass 1. (Eliminating the pass structure altogether would be a better but more involved fix.) We used to decide whether the module had any type errors by testing whether the list of error messages gathered during pass 2 was empty or not. To keep this working, if the code shifted to pass 1 finds an error, it now records the presence of that error in the affected type definition, so it can be reported in pass 2. (Simply threading a "have we discovered a type error yet" indication through both pass 1 and 2 would have been a more direct solution, but it would cause bad conflicts with my work on the item list. I plan to revisit this when that change is done.) compiler/add_pragma.m: Move the processing of foreign enum pragmas from pass 3 to pass 2. compiler/add_type.m: If there is a problem with a type definition, record that fact in the type definition itself, as explained above, and report it in the predicate process_type_defn, which is invoked in pass 2. Fix the formatting of some other error messages, and of some comments. compiler/hlds_data.m: Provide a mechanism to record the presence of type errors in type definitions. compiler/make_hlds_passes.m: Move the processing of type definitions from pass 2 to pass 1. compiler/post_typecheck.m: Don't print error messages about type definitions for which we have already reported errors, since the errors discovered here would almost certainly be caused by our incomplete recovery from the original error. compiler/type_ctor_info.m: Conform to the changes above. tests/hard_coded/bug_pack_bits.{m,exp}: The Mantis test case, slightly modified. tests/hard_coded/Mmakefile: Enable the new test case. tests/invalid/foreign_type_missing.err_exp: tests/invalid/foreign_type_visibility.err_exp: Expect the relevant error messages with the fixed formatting.
97 lines
2.6 KiB
Mathematica
97 lines
2.6 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module bug_pack_bits.
|
|
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
main(!IO) :-
|
|
getaddrinfo(AddrInfos),
|
|
io.write_string("getaddrinfo for www.google.com:\n", !IO),
|
|
foldl(write_addrinfo, AddrInfos, !IO).
|
|
|
|
:- pred write_addrinfo(addrinfo::in, io::di, io::uo) is det.
|
|
|
|
write_addrinfo(addrinfo(Family, Socktype, ProtoNum), !IO) :-
|
|
io.format("Family: %-10s Socktype: %-12s Protocol: %s\n",
|
|
[s(string(Family) ++ ","), s(string(Socktype) ++ ","), s(ProtoName)],
|
|
!IO),
|
|
ProtoName = string(ProtoNum).
|
|
|
|
:- type addrinfo
|
|
---> addrinfo(
|
|
ai_family :: family,
|
|
ai_socktype :: socktype,
|
|
ai_protocol :: protocol_num
|
|
).
|
|
|
|
:- pred getaddrinfo(list(addrinfo)::out) is det.
|
|
|
|
getaddrinfo([addrinfo(fam_inet, sock_stream, 89),
|
|
addrinfo(fam_inet, sock_dgram, 80),
|
|
addrinfo(fam_inet6, sock_stream, 80),
|
|
addrinfo(fam_inet6, sock_dgram, 80)]).
|
|
|
|
% Protocol number.
|
|
%
|
|
% See getprotobyname/4.
|
|
%
|
|
:- type protocol_num == int.
|
|
|
|
% The socket family. This type is incomplete, support for socket
|
|
% families such as IPX or appletalk will probably never be added.
|
|
% However Unix domain sockets may be added in the future.
|
|
%
|
|
:- type family
|
|
---> fam_inet
|
|
; fam_inet6.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% The socket type. Informally (for fam_inet and fam_inet6) these
|
|
% correspond to TCP and UDP respectively. More precicely these specify
|
|
% the socket's behavour, the protocol is optionally specified
|
|
% seperately.
|
|
%
|
|
:- type socktype
|
|
---> sock_stream
|
|
; sock_dgram.
|
|
|
|
:- pragma foreign_decl("C",
|
|
"
|
|
#ifdef MR_WIN32
|
|
#include ""mercury_windows.h""
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#else
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
").
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% This list of address families is from socket(2) on linux.
|
|
%
|
|
:- pragma foreign_enum("C", family/0, [
|
|
fam_inet - "AF_INET",
|
|
fam_inet6 - "AF_INET6"
|
|
]).
|
|
|
|
:- pragma foreign_enum("C", socktype/0, [
|
|
sock_stream - "SOCK_STREAM",
|
|
sock_dgram - "SOCK_DGRAM"
|
|
]).
|
|
|
|
%---------------------------------------------------------------------------%
|