Branch data Line data Source code
1 : : // unsafe.cc -- Go frontend builtin unsafe package.
2 : :
3 : : // Copyright 2009 The Go Authors. All rights reserved.
4 : : // Use of this source code is governed by a BSD-style
5 : : // license that can be found in the LICENSE file.
6 : :
7 : : #include "go-system.h"
8 : :
9 : : #include "go-c.h"
10 : : #include "types.h"
11 : : #include "gogo.h"
12 : :
13 : : // Set up the builtin unsafe package.
14 : :
15 : : void
16 : 1471 : Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
17 : : Location location)
18 : : {
19 : 1471 : bool add_to_globals;
20 : 2942 : Package* package = this->add_imported_package("unsafe", local_name,
21 : : is_local_name_exported,
22 : : "unsafe", "unsafe", location,
23 : 1471 : &add_to_globals);
24 : :
25 : 1471 : if (package == NULL)
26 : : {
27 : 0 : go_assert(saw_errors());
28 : 0 : return;
29 : : }
30 : :
31 : 1471 : package->set_location(location);
32 : 1471 : this->imports_.insert(std::make_pair("unsafe", package));
33 : :
34 : 1471 : this->add_unsafe_bindings(package);
35 : :
36 : 1471 : Named_object* pointer_no = package->bindings()->lookup_local("Pointer");
37 : 1471 : pointer_no->type_value()->set_is_visible();
38 : :
39 : 1471 : if (add_to_globals)
40 : : {
41 : 2 : Bindings* bindings = package->bindings();
42 : 14 : for (Bindings::const_declarations_iterator p =
43 : 2 : bindings->begin_declarations();
44 : 14 : p != bindings->end_declarations();
45 : 12 : ++p)
46 : 12 : this->add_dot_import_object(p->second);
47 : : }
48 : : }
49 : :
50 : : // Add the unsafe bindings to the Package object. This should
51 : : // probably be driven by a table.
52 : :
53 : : void
54 : 12432 : Gogo::add_unsafe_bindings(Package* package)
55 : : {
56 : 12432 : Bindings* bindings = package->bindings();
57 : :
58 : 12432 : if (bindings->lookup_local("Sizeof") != NULL)
59 : : {
60 : : // Already done by an earlier import.
61 : 8809 : return;
62 : : }
63 : :
64 : 3623 : Location bloc = Linemap::predeclared_location();
65 : :
66 : : // The type may have already been created by an import.
67 : 3623 : Named_object* no = bindings->lookup("Pointer");
68 : 3623 : if (no == NULL)
69 : : {
70 : 3623 : Type* type = Type::make_pointer_type(Type::make_void_type());
71 : 3623 : no = bindings->add_type("Pointer", package, type,
72 : : Linemap::unknown_location());
73 : : }
74 : : else
75 : : {
76 : 0 : go_assert(no->package() == package);
77 : 0 : go_assert(no->is_type());
78 : 0 : go_assert(no->type_value()->is_unsafe_pointer_type());
79 : : }
80 : 3623 : Named_type* pointer_type = no->type_value();
81 : :
82 : : // This may be called during an import, so the type may not be
83 : : // visible yet.
84 : 3623 : pointer_type->clear_is_visible();
85 : :
86 : 3623 : Type* uintptr_type = Type::lookup_integer_type("uintptr");
87 : :
88 : : // Sizeof.
89 : 3623 : Typed_identifier_list* results = new Typed_identifier_list;
90 : 3623 : results->push_back(Typed_identifier("", uintptr_type, bloc));
91 : 3623 : Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
92 : 3623 : fntype->set_is_builtin();
93 : 3623 : bindings->add_function_declaration("Sizeof", package, fntype, bloc);
94 : :
95 : : // Offsetof.
96 : 3623 : results = new Typed_identifier_list;
97 : 3623 : results->push_back(Typed_identifier("", uintptr_type, bloc));
98 : 3623 : fntype = Type::make_function_type(NULL, NULL, results, bloc);
99 : 3623 : fntype->set_is_varargs();
100 : 3623 : fntype->set_is_builtin();
101 : 3623 : bindings->add_function_declaration("Offsetof", package, fntype, bloc);
102 : :
103 : : // Alignof.
104 : 3623 : results = new Typed_identifier_list;
105 : 3623 : results->push_back(Typed_identifier("", uintptr_type, bloc));
106 : 3623 : fntype = Type::make_function_type(NULL, NULL, results, bloc);
107 : 3623 : fntype->set_is_varargs();
108 : 3623 : fntype->set_is_builtin();
109 : 3623 : bindings->add_function_declaration("Alignof", package, fntype, bloc);
110 : :
111 : : // Add.
112 : 3623 : results = new Typed_identifier_list;
113 : 3623 : results->push_back(Typed_identifier("", pointer_type, bloc));
114 : 3623 : fntype = Type::make_function_type(NULL, NULL, results, bloc);
115 : 3623 : fntype->set_is_builtin();
116 : 3623 : bindings->add_function_declaration("Add", package, fntype, bloc);
117 : :
118 : : // Slice.
119 : 3623 : fntype = Type::make_function_type(NULL, NULL, NULL, bloc);
120 : 3623 : fntype->set_is_builtin();
121 : 3623 : bindings->add_function_declaration("Slice", package, fntype, bloc);
122 : :
123 : 3623 : if (!this->imported_unsafe_)
124 : : {
125 : 3623 : go_imported_unsafe();
126 : 3623 : this->imported_unsafe_ = true;
127 : : }
128 : : }
|