summaryrefslogtreecommitdiff
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.cc146
1 files changed, 146 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/unsafe.cc b/gcc/go/gofrontend/unsafe.cc
new file mode 100644
index 000000000..9d51b4d94
--- /dev/null
+++ b/gcc/go/gofrontend/unsafe.cc
@@ -0,0 +1,146 @@
+// unsafe.cc -- Go frontend builtin unsafe package.
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go-system.h"
+
+#include "go-c.h"
+#include "types.h"
+#include "gogo.h"
+
+// Set up the builtin unsafe package. This should probably be driven
+// by a table.
+
+void
+Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
+ source_location location)
+{
+ location_t bloc = BUILTINS_LOCATION;
+
+ bool add_to_globals;
+ Package* package = this->add_imported_package("unsafe", local_name,
+ is_local_name_exported,
+ "libgo_unsafe",
+ location, &add_to_globals);
+
+ if (package == NULL)
+ {
+ gcc_assert(saw_errors());
+ return;
+ }
+
+ package->set_is_imported();
+
+ Bindings* bindings = package->bindings();
+
+ // The type may have already been created by an import.
+ Named_object* no = package->bindings()->lookup("Pointer");
+ if (no == NULL)
+ {
+ Type* type = Type::make_pointer_type(Type::make_void_type());
+ no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION);
+ }
+ else
+ {
+ gcc_assert(no->package() == package);
+ gcc_assert(no->is_type());
+ gcc_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);
+
+ Type* int_type = this->lookup_global("int")->type_value();
+
+ // Sizeof.
+ Typed_identifier_list* results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", int_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_named_object(no);
+
+ // Offsetof.
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", int_type, bloc));
+ 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_named_object(no);
+
+ // Alignof.
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", int_type, bloc));
+ 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_named_object(no);
+
+ // Typeof.
+ Type* empty_interface = Type::make_interface_type(NULL, bloc);
+ Typed_identifier_list* parameters = new Typed_identifier_list;
+ parameters->push_back(Typed_identifier("i", empty_interface, bloc));
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", empty_interface, bloc));
+ fntype = Type::make_function_type(NULL, parameters, results, bloc);
+ no = bindings->add_function_declaration("Typeof", package, fntype, bloc);
+ if (add_to_globals)
+ this->add_named_object(no);
+
+ // Reflect.
+ parameters = new Typed_identifier_list;
+ parameters->push_back(Typed_identifier("it", empty_interface, bloc));
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", empty_interface, bloc));
+ results->push_back(Typed_identifier("", pointer_type, bloc));
+ fntype = Type::make_function_type(NULL, parameters, results, bloc);
+ no = bindings->add_function_declaration("Reflect", package, fntype, bloc);
+ if (add_to_globals)
+ this->add_named_object(no);
+
+ // Unreflect.
+ parameters = new Typed_identifier_list;
+ parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
+ parameters->push_back(Typed_identifier("addr", pointer_type, bloc));
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", empty_interface, bloc));
+ fntype = Type::make_function_type(NULL, parameters, results, bloc);
+ no = bindings->add_function_declaration("Unreflect", package, fntype, bloc);
+ if (add_to_globals)
+ this->add_named_object(no);
+
+ // New.
+ parameters = new Typed_identifier_list;
+ parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", pointer_type, bloc));
+ fntype = Type::make_function_type(NULL, parameters, results, bloc);
+ no = bindings->add_function_declaration("New", package, fntype, bloc);
+ if (add_to_globals)
+ this->add_named_object(no);
+
+ // NewArray.
+ parameters = new Typed_identifier_list;
+ parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
+ parameters->push_back(Typed_identifier("n", int_type, bloc));
+ results = new Typed_identifier_list;
+ results->push_back(Typed_identifier("", pointer_type, bloc));
+ fntype = Type::make_function_type(NULL, parameters, results, bloc);
+ no = bindings->add_function_declaration("NewArray", package, fntype, bloc);
+ if (add_to_globals)
+ this->add_named_object(no);
+
+ if (!this->imported_unsafe_)
+ {
+ go_imported_unsafe();
+ this->imported_unsafe_ = true;
+ }
+}