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