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 4413 : Package* package = this->add_imported_package("unsafe", local_name,
21 : is_local_name_exported,
22 2942 : "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 7246 : 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 7246 : 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 7246 : 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 7246 : 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 : }
|