aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/unsafe.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go/gofrontend/unsafe.cc')
-rw-r--r--gcc/go/gofrontend/unsafe.cc68
1 files changed, 51 insertions, 17 deletions
diff --git a/gcc/go/gofrontend/unsafe.cc b/gcc/go/gofrontend/unsafe.cc
index 9ed5b9d..c4a9346 100644
--- a/gcc/go/gofrontend/unsafe.cc
+++ b/gcc/go/gofrontend/unsafe.cc
@@ -10,15 +10,12 @@
#include "types.h"
#include "gogo.h"
-// Set up the builtin unsafe package. This should probably be driven
-// by a table.
+// Set up the builtin unsafe package.
void
Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
Location location)
{
- Location bloc = Linemap::predeclared_location();
-
bool add_to_globals;
Package* package = this->add_imported_package("unsafe", local_name,
is_local_name_exported,
@@ -34,10 +31,40 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
package->set_location(location);
this->imports_.insert(std::make_pair("unsafe", package));
+ this->add_unsafe_bindings(package);
+
+ Named_object* pointer_no = package->bindings()->lookup_local("Pointer");
+ pointer_no->type_value()->set_is_visible();
+
+ if (add_to_globals)
+ {
+ Bindings* bindings = package->bindings();
+ for (Bindings::const_declarations_iterator p =
+ bindings->begin_declarations();
+ p != bindings->end_declarations();
+ ++p)
+ this->add_dot_import_object(p->second);
+ }
+}
+
+// Add the unsafe bindings to the Package object. This should
+// probably be driven by a table.
+
+void
+Gogo::add_unsafe_bindings(Package* package)
+{
Bindings* bindings = package->bindings();
+ if (bindings->lookup_local("Sizeof") != NULL)
+ {
+ // Already done by an earlier import.
+ return;
+ }
+
+ Location bloc = Linemap::predeclared_location();
+
// The type may have already been created by an import.
- Named_object* no = package->bindings()->lookup("Pointer");
+ Named_object* no = bindings->lookup("Pointer");
if (no == NULL)
{
Type* type = Type::make_pointer_type(Type::make_void_type());
@@ -49,11 +76,12 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
go_assert(no->package() == package);
go_assert(no->is_type());
go_assert(no->type_value()->is_unsafe_pointer_type());
- no->type_value()->set_is_visible();
}
Named_type* pointer_type = no->type_value();
- if (add_to_globals)
- this->add_named_type(pointer_type);
+
+ // This may be called during an import, so the type may not be
+ // visible yet.
+ pointer_type->clear_is_visible();
Type* uintptr_type = Type::lookup_integer_type("uintptr");
@@ -62,9 +90,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
results->push_back(Typed_identifier("", uintptr_type, bloc));
Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
fntype->set_is_builtin();
- no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
- if (add_to_globals)
- this->add_dot_import_object(no);
+ bindings->add_function_declaration("Sizeof", package, fntype, bloc);
// Offsetof.
results = new Typed_identifier_list;
@@ -72,9 +98,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
fntype = Type::make_function_type(NULL, NULL, results, bloc);
fntype->set_is_varargs();
fntype->set_is_builtin();
- no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
- if (add_to_globals)
- this->add_dot_import_object(no);
+ bindings->add_function_declaration("Offsetof", package, fntype, bloc);
// Alignof.
results = new Typed_identifier_list;
@@ -82,9 +106,19 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
fntype = Type::make_function_type(NULL, NULL, results, bloc);
fntype->set_is_varargs();
fntype->set_is_builtin();
- no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
- if (add_to_globals)
- this->add_dot_import_object(no);
+ bindings->add_function_declaration("Alignof", package, fntype, bloc);
+
+ // Add.
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", pointer_type, bloc));
+ fntype = Type::make_function_type(NULL, NULL, results, bloc);
+ fntype->set_is_builtin();
+ bindings->add_function_declaration("Add", package, fntype, bloc);
+
+ // Slice.
+ fntype = Type::make_function_type(NULL, NULL, NULL, bloc);
+ fntype->set_is_builtin();
+ bindings->add_function_declaration("Slice", package, fntype, bloc);
if (!this->imported_unsafe_)
{