OSDN Git Service

compiler, libgo: unsafe.{Sizeof,Alignof,Offsetof} return uintptr.
[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                     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                                                 "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_location(location);
35   package->set_is_imported();
36
37   this->imports_.insert(std::make_pair("unsafe", package));
38
39   Bindings* bindings = package->bindings();
40
41   // The type may have already been created by an import.
42   Named_object* no = package->bindings()->lookup("Pointer");
43   if (no == NULL)
44     {
45       Type* type = Type::make_pointer_type(Type::make_void_type());
46       no = bindings->add_type("Pointer", package, type,
47                               Linemap::unknown_location());
48     }
49   else
50     {
51       go_assert(no->package() == package);
52       go_assert(no->is_type());
53       go_assert(no->type_value()->is_unsafe_pointer_type());
54       no->type_value()->set_is_visible();
55     }
56   Named_type* pointer_type = no->type_value();
57   if (add_to_globals)
58     this->add_named_type(pointer_type);
59
60   Type* uintptr_type = Type::lookup_integer_type("uintptr");
61
62   // Sizeof.
63   Typed_identifier_list* results = new Typed_identifier_list;
64   results->push_back(Typed_identifier("", uintptr_type, bloc));
65   Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
66   fntype->set_is_builtin();
67   no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
68   if (add_to_globals)
69     this->add_named_object(no);
70
71   // Offsetof.
72   results = new Typed_identifier_list;
73   results->push_back(Typed_identifier("", uintptr_type, bloc));
74   fntype = Type::make_function_type(NULL, NULL, results, bloc);
75   fntype->set_is_varargs();
76   fntype->set_is_builtin();
77   no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
78   if (add_to_globals)
79     this->add_named_object(no);
80
81   // Alignof.
82   results = new Typed_identifier_list;
83   results->push_back(Typed_identifier("", uintptr_type, bloc));
84   fntype = Type::make_function_type(NULL, NULL, results, bloc);
85   fntype->set_is_varargs();
86   fntype->set_is_builtin();
87   no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
88   if (add_to_globals)
89     this->add_named_object(no);
90
91   if (!this->imported_unsafe_)
92     {
93       go_imported_unsafe();
94       this->imported_unsafe_ = true;
95     }
96 }