1 // unsafe.cc -- Go frontend builtin unsafe package.
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.
13 // Set up the builtin unsafe package.
16 Gogo::import_unsafe(const std::string
& local_name
, bool is_local_name_exported
,
20 Package
* package
= this->add_imported_package("unsafe", local_name
,
21 is_local_name_exported
,
22 "unsafe", "unsafe", location
,
27 go_assert(saw_errors());
31 package
->set_location(location
);
32 this->imports_
.insert(std::make_pair("unsafe", package
));
34 this->add_unsafe_bindings(package
);
36 Named_object
* pointer_no
= package
->bindings()->lookup_local("Pointer");
37 pointer_no
->type_value()->set_is_visible();
41 Bindings
* bindings
= package
->bindings();
42 for (Bindings::const_declarations_iterator p
=
43 bindings
->begin_declarations();
44 p
!= bindings
->end_declarations();
46 this->add_dot_import_object(p
->second
);
50 // Add the unsafe bindings to the Package object. This should
51 // probably be driven by a table.
54 Gogo::add_unsafe_bindings(Package
* package
)
56 Bindings
* bindings
= package
->bindings();
58 if (bindings
->lookup_local("Sizeof") != NULL
)
60 // Already done by an earlier import.
64 Location bloc
= Linemap::predeclared_location();
66 // The type may have already been created by an import.
67 Named_object
* no
= bindings
->lookup("Pointer");
70 Type
* type
= Type::make_pointer_type(Type::make_void_type());
71 no
= bindings
->add_type("Pointer", package
, type
,
72 Linemap::unknown_location());
76 go_assert(no
->package() == package
);
77 go_assert(no
->is_type());
78 go_assert(no
->type_value()->is_unsafe_pointer_type());
80 Named_type
* pointer_type
= no
->type_value();
82 // This may be called during an import, so the type may not be
84 pointer_type
->clear_is_visible();
86 Type
* uintptr_type
= Type::lookup_integer_type("uintptr");
89 Typed_identifier_list
* results
= new Typed_identifier_list
;
90 results
->push_back(Typed_identifier("", uintptr_type
, bloc
));
91 Function_type
* fntype
= Type::make_function_type(NULL
, NULL
, results
, bloc
);
92 fntype
->set_is_builtin();
93 bindings
->add_function_declaration("Sizeof", package
, fntype
, bloc
);
96 results
= new Typed_identifier_list
;
97 results
->push_back(Typed_identifier("", uintptr_type
, bloc
));
98 fntype
= Type::make_function_type(NULL
, NULL
, results
, bloc
);
99 fntype
->set_is_varargs();
100 fntype
->set_is_builtin();
101 bindings
->add_function_declaration("Offsetof", package
, fntype
, bloc
);
104 results
= new Typed_identifier_list
;
105 results
->push_back(Typed_identifier("", uintptr_type
, bloc
));
106 fntype
= Type::make_function_type(NULL
, NULL
, results
, bloc
);
107 fntype
->set_is_varargs();
108 fntype
->set_is_builtin();
109 bindings
->add_function_declaration("Alignof", package
, fntype
, bloc
);
112 results
= new Typed_identifier_list
;
113 results
->push_back(Typed_identifier("", pointer_type
, bloc
));
114 fntype
= Type::make_function_type(NULL
, NULL
, results
, bloc
);
115 fntype
->set_is_builtin();
116 bindings
->add_function_declaration("Add", package
, fntype
, bloc
);
119 fntype
= Type::make_function_type(NULL
, NULL
, NULL
, bloc
);
120 fntype
->set_is_builtin();
121 bindings
->add_function_declaration("Slice", package
, fntype
, bloc
);
123 if (!this->imported_unsafe_
)
125 go_imported_unsafe();
126 this->imported_unsafe_
= true;