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  }