OSDN Git Service

80b367cc46d4b6fc03cfc44236e00a99a642bf8d
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / unsafe.cc
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
17 Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
18                     source_location location)
19 {
20   location_t bloc = BUILTINS_LOCATION;
21
22   bool add_to_globals;
23   Package* package = this->add_imported_package("unsafe", local_name,
24                                                 is_local_name_exported,
25                                                 "libgo_unsafe",
26                                                 location, &add_to_globals);
27
28   if (package == NULL)
29     {
30       go_assert(saw_errors());
31       return;
32     }
33
34   package->set_is_imported();
35
36   Bindings* bindings = package->bindings();
37
38   // The type may have already been created by an import.
39   Named_object* no = package->bindings()->lookup("Pointer");
40   if (no == NULL)
41     {
42       Type* type = Type::make_pointer_type(Type::make_void_type());
43       no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION);
44     }
45   else
46     {
47       go_assert(no->package() == package);
48       go_assert(no->is_type());
49       go_assert(no->type_value()->is_unsafe_pointer_type());
50       no->type_value()->set_is_visible();
51     }
52   Named_type* pointer_type = no->type_value();
53   if (add_to_globals)
54     this->add_named_type(pointer_type);
55
56   Type* int_type = this->lookup_global("int")->type_value();
57
58   // Sizeof.
59   Typed_identifier_list* results = new Typed_identifier_list;
60   results->push_back(Typed_identifier("", int_type, bloc));
61   Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
62   fntype->set_is_builtin();
63   no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
64   if (add_to_globals)
65     this->add_named_object(no);
66
67   // Offsetof.
68   results = new Typed_identifier_list;
69   results->push_back(Typed_identifier("", int_type, bloc));
70   fntype = Type::make_function_type(NULL, NULL, results, bloc);
71   fntype->set_is_varargs();
72   fntype->set_is_builtin();
73   no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
74   if (add_to_globals)
75     this->add_named_object(no);
76
77   // Alignof.
78   results = new Typed_identifier_list;
79   results->push_back(Typed_identifier("", int_type, bloc));
80   fntype = Type::make_function_type(NULL, NULL, results, bloc);
81   fntype->set_is_varargs();
82   fntype->set_is_builtin();
83   no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
84   if (add_to_globals)
85     this->add_named_object(no);
86
87   // Typeof.
88   Type* empty_interface = Type::make_interface_type(NULL, bloc);
89   Typed_identifier_list* parameters = new Typed_identifier_list;
90   parameters->push_back(Typed_identifier("i", empty_interface, bloc));
91   results = new Typed_identifier_list;
92   results->push_back(Typed_identifier("", empty_interface, bloc));
93   fntype = Type::make_function_type(NULL, parameters, results, bloc);
94   no = bindings->add_function_declaration("Typeof", package, fntype, bloc);
95   if (add_to_globals)
96     this->add_named_object(no);
97
98   // Reflect.
99   parameters = new Typed_identifier_list;
100   parameters->push_back(Typed_identifier("it", empty_interface, bloc));
101   results = new Typed_identifier_list;
102   results->push_back(Typed_identifier("", empty_interface, bloc));
103   results->push_back(Typed_identifier("", pointer_type, bloc));
104   fntype = Type::make_function_type(NULL, parameters, results, bloc);
105   no = bindings->add_function_declaration("Reflect", package, fntype, bloc);
106   if (add_to_globals)
107     this->add_named_object(no);
108
109   // Unreflect.
110   parameters = new Typed_identifier_list;
111   parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
112   parameters->push_back(Typed_identifier("addr", pointer_type, bloc));
113   results = new Typed_identifier_list;
114   results->push_back(Typed_identifier("", empty_interface, bloc));
115   fntype = Type::make_function_type(NULL, parameters, results, bloc);
116   no = bindings->add_function_declaration("Unreflect", package, fntype, bloc);
117   if (add_to_globals)
118     this->add_named_object(no);
119
120   // New.
121   parameters = new Typed_identifier_list;
122   parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
123   results = new Typed_identifier_list;
124   results->push_back(Typed_identifier("", pointer_type, bloc));
125   fntype = Type::make_function_type(NULL, parameters, results, bloc);
126   no = bindings->add_function_declaration("New", package, fntype, bloc);
127   if (add_to_globals)
128     this->add_named_object(no);
129
130   // NewArray.
131   parameters = new Typed_identifier_list;
132   parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
133   parameters->push_back(Typed_identifier("n", int_type, bloc));
134   results = new Typed_identifier_list;
135   results->push_back(Typed_identifier("", pointer_type, bloc));
136   fntype = Type::make_function_type(NULL, parameters, results, bloc);
137   no = bindings->add_function_declaration("NewArray", package, fntype, bloc);
138   if (add_to_globals)
139     this->add_named_object(no);
140
141   if (!this->imported_unsafe_)
142     {
143       go_imported_unsafe();
144       this->imported_unsafe_ = true;
145     }
146 }