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. This should probably be driven
14 // by a table.
15
16 void
import_unsafe(const std::string & local_name,bool is_local_name_exported,Location location)17 Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
18 Location location)
19 {
20 Location bloc = Linemap::predeclared_location();
21
22 bool add_to_globals;
23 Package* package = this->add_imported_package("unsafe", local_name,
24 is_local_name_exported,
25 "unsafe", "unsafe", location,
26 &add_to_globals);
27
28 if (package == NULL)
29 {
30 go_assert(saw_errors());
31 return;
32 }
33
34 package->set_location(location);
35 this->imports_.insert(std::make_pair("unsafe", package));
36
37 Bindings* bindings = package->bindings();
38
39 // The type may have already been created by an import.
40 Named_object* no = package->bindings()->lookup("Pointer");
41 if (no == NULL)
42 {
43 Type* type = Type::make_pointer_type(Type::make_void_type());
44 no = bindings->add_type("Pointer", package, type,
45 Linemap::unknown_location());
46 }
47 else
48 {
49 go_assert(no->package() == package);
50 go_assert(no->is_type());
51 go_assert(no->type_value()->is_unsafe_pointer_type());
52 no->type_value()->set_is_visible();
53 }
54 Named_type* pointer_type = no->type_value();
55 if (add_to_globals)
56 this->add_named_type(pointer_type);
57
58 Type* uintptr_type = Type::lookup_integer_type("uintptr");
59
60 // Sizeof.
61 Typed_identifier_list* results = new Typed_identifier_list;
62 results->push_back(Typed_identifier("", uintptr_type, bloc));
63 Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
64 fntype->set_is_builtin();
65 no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
66 if (add_to_globals)
67 this->add_dot_import_object(no);
68
69 // Offsetof.
70 results = new Typed_identifier_list;
71 results->push_back(Typed_identifier("", uintptr_type, bloc));
72 fntype = Type::make_function_type(NULL, NULL, results, bloc);
73 fntype->set_is_varargs();
74 fntype->set_is_builtin();
75 no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
76 if (add_to_globals)
77 this->add_dot_import_object(no);
78
79 // Alignof.
80 results = new Typed_identifier_list;
81 results->push_back(Typed_identifier("", uintptr_type, bloc));
82 fntype = Type::make_function_type(NULL, NULL, results, bloc);
83 fntype->set_is_varargs();
84 fntype->set_is_builtin();
85 no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
86 if (add_to_globals)
87 this->add_dot_import_object(no);
88
89 if (!this->imported_unsafe_)
90 {
91 go_imported_unsafe();
92 this->imported_unsafe_ = true;
93 }
94 }
95