github.com/ronhuafeng/gofrontend@v0.0.0-20220715151246-ff23266b8bc5/go/unsafe.cc (about) 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. 14 15 void 16 Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, 17 Location location) 18 { 19 bool add_to_globals; 20 Package* package = this->add_imported_package("unsafe", local_name, 21 is_local_name_exported, 22 "unsafe", "unsafe", location, 23 &add_to_globals); 24 25 if (package == NULL) 26 { 27 go_assert(saw_errors()); 28 return; 29 } 30 31 package->set_location(location); 32 this->imports_.insert(std::make_pair("unsafe", package)); 33 34 this->add_unsafe_bindings(package); 35 36 Named_object* pointer_no = package->bindings()->lookup_local("Pointer"); 37 pointer_no->type_value()->set_is_visible(); 38 39 if (add_to_globals) 40 { 41 Bindings* bindings = package->bindings(); 42 for (Bindings::const_declarations_iterator p = 43 bindings->begin_declarations(); 44 p != bindings->end_declarations(); 45 ++p) 46 this->add_dot_import_object(p->second); 47 } 48 } 49 50 // Add the unsafe bindings to the Package object. This should 51 // probably be driven by a table. 52 53 void 54 Gogo::add_unsafe_bindings(Package* package) 55 { 56 Bindings* bindings = package->bindings(); 57 58 if (bindings->lookup_local("Sizeof") != NULL) 59 { 60 // Already done by an earlier import. 61 return; 62 } 63 64 Location bloc = Linemap::predeclared_location(); 65 66 // The type may have already been created by an import. 67 Named_object* no = bindings->lookup("Pointer"); 68 if (no == NULL) 69 { 70 Type* type = Type::make_pointer_type(Type::make_void_type()); 71 no = bindings->add_type("Pointer", package, type, 72 Linemap::unknown_location()); 73 } 74 else 75 { 76 go_assert(no->package() == package); 77 go_assert(no->is_type()); 78 go_assert(no->type_value()->is_unsafe_pointer_type()); 79 } 80 Named_type* pointer_type = no->type_value(); 81 82 // This may be called during an import, so the type may not be 83 // visible yet. 84 pointer_type->clear_is_visible(); 85 86 Type* uintptr_type = Type::lookup_integer_type("uintptr"); 87 88 // Sizeof. 89 Typed_identifier_list* results = new Typed_identifier_list; 90 results->push_back(Typed_identifier("", uintptr_type, bloc)); 91 Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc); 92 fntype->set_is_builtin(); 93 bindings->add_function_declaration("Sizeof", package, fntype, bloc); 94 95 // Offsetof. 96 results = new Typed_identifier_list; 97 results->push_back(Typed_identifier("", uintptr_type, bloc)); 98 fntype = Type::make_function_type(NULL, NULL, results, bloc); 99 fntype->set_is_varargs(); 100 fntype->set_is_builtin(); 101 bindings->add_function_declaration("Offsetof", package, fntype, bloc); 102 103 // Alignof. 104 results = new Typed_identifier_list; 105 results->push_back(Typed_identifier("", uintptr_type, bloc)); 106 fntype = Type::make_function_type(NULL, NULL, results, bloc); 107 fntype->set_is_varargs(); 108 fntype->set_is_builtin(); 109 bindings->add_function_declaration("Alignof", package, fntype, bloc); 110 111 // Add. 112 results = new Typed_identifier_list; 113 results->push_back(Typed_identifier("", pointer_type, bloc)); 114 fntype = Type::make_function_type(NULL, NULL, results, bloc); 115 fntype->set_is_builtin(); 116 bindings->add_function_declaration("Add", package, fntype, bloc); 117 118 // Slice. 119 fntype = Type::make_function_type(NULL, NULL, NULL, bloc); 120 fntype->set_is_builtin(); 121 bindings->add_function_declaration("Slice", package, fntype, bloc); 122 123 if (!this->imported_unsafe_) 124 { 125 go_imported_unsafe(); 126 this->imported_unsafe_ = true; 127 } 128 }