github.com/kidsbmilk/gofronted_all@v0.0.0-20220701224323-6479d5976c5d/go/go.cc (about) 1 // go.cc -- Go frontend main file for gcc. 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 "go-diagnostics.h" 11 12 #include "lex.h" 13 #include "parse.h" 14 #include "backend.h" 15 #include "gogo.h" 16 17 // The data structures we build to represent the file. 18 static Gogo* gogo; 19 20 // Create the main IR data structure. 21 22 GO_EXTERN_C 23 void 24 go_create_gogo(const struct go_create_gogo_args* args) 25 { 26 go_assert(::gogo == NULL); 27 ::gogo = new Gogo(args->backend, args->linemap, args->int_type_size, 28 args->pointer_size); 29 30 if (args->pkgpath != NULL) 31 ::gogo->set_pkgpath(args->pkgpath); 32 else if (args->prefix != NULL) 33 ::gogo->set_prefix(args->prefix); 34 35 if (args->relative_import_path != NULL) 36 ::gogo->set_relative_import_path(args->relative_import_path); 37 ::gogo->set_check_divide_by_zero(args->check_divide_by_zero); 38 ::gogo->set_check_divide_overflow(args->check_divide_overflow); 39 if (args->compiling_runtime) 40 ::gogo->set_compiling_runtime(args->compiling_runtime); 41 if (args->c_header != NULL) 42 ::gogo->set_c_header(args->c_header); 43 if (args->embedcfg != NULL) 44 ::gogo->read_embedcfg(args->embedcfg); 45 ::gogo->set_debug_escape_level(args->debug_escape_level); 46 if (args->debug_escape_hash != NULL) 47 ::gogo->set_debug_escape_hash(args->debug_escape_hash); 48 ::gogo->set_nil_check_size_threshold(args->nil_check_size_threshold); 49 if (args->debug_optimization) 50 ::gogo->set_debug_optimization(args->debug_optimization); 51 if (args->need_eqtype) 52 ::gogo->set_need_eqtype(args->need_eqtype); 53 } 54 55 // Parse the input files. 56 57 GO_EXTERN_C 58 void 59 go_parse_input_files(const char** filenames, unsigned int filename_count, 60 bool only_check_syntax, bool) 61 { 62 go_assert(filename_count > 0); 63 64 Lex::Linknames all_linknames; 65 for (unsigned int i = 0; i < filename_count; ++i) 66 { 67 if (i > 0) 68 ::gogo->clear_file_scope(); 69 70 const char* filename = filenames[i]; 71 FILE* file; 72 if (strcmp(filename, "-") == 0) 73 file = stdin; 74 else 75 { 76 file = fopen(filename, "r"); 77 if (file == NULL) 78 go_fatal_error(Linemap::unknown_location(), 79 "cannot open %s: %m", filename); 80 } 81 82 Lex lexer(filename, file, ::gogo->linemap()); 83 84 Parse parse(&lexer, ::gogo); 85 parse.program(); 86 87 if (strcmp(filename, "-") != 0) 88 fclose(file); 89 90 Lex::Linknames* linknames = lexer.get_and_clear_linknames(); 91 if (linknames != NULL) 92 { 93 if (!::gogo->current_file_imported_unsafe()) 94 { 95 for (Lex::Linknames::const_iterator p = linknames->begin(); 96 p != linknames->end(); 97 ++p) 98 go_error_at(p->second.loc, 99 ("%<//go:linkname%> only allowed in Go files that " 100 "import \"unsafe\"")); 101 } 102 all_linknames.insert(linknames->begin(), linknames->end()); 103 } 104 } 105 106 ::gogo->clear_file_scope(); 107 108 // If the global predeclared names are referenced but not defined, 109 // define them now. 110 ::gogo->define_global_names(); 111 112 // Apply any go:linkname directives. 113 for (Lex::Linknames::const_iterator p = all_linknames.begin(); 114 p != all_linknames.end(); 115 ++p) 116 ::gogo->add_linkname(p->first, p->second.is_exported, p->second.ext_name, 117 p->second.loc); 118 119 // Finalize method lists and build stub methods for named types. 120 ::gogo->finalize_methods(); 121 122 // Check that functions have a terminating statement. 123 ::gogo->check_return_statements(); 124 125 // Now that we have seen all the names, lower the parse tree into a 126 // form which is easier to use. 127 ::gogo->lower_parse_tree(); 128 129 // At this point we have handled all inline functions, so we no 130 // longer need the linemap. 131 ::gogo->linemap()->stop(); 132 133 // Create function descriptors as needed. 134 ::gogo->create_function_descriptors(); 135 136 // Now that we have seen all the names, verify that types are 137 // correct. 138 ::gogo->verify_types(); 139 140 // Work out types of unspecified constants and variables. 141 ::gogo->determine_types(); 142 143 // Check types and issue errors as appropriate. 144 ::gogo->check_types(); 145 146 if (only_check_syntax) 147 return; 148 149 // Record global variable initializer dependencies. 150 ::gogo->record_global_init_refs(); 151 152 // Do simple deadcode elimination. 153 ::gogo->remove_deadcode(); 154 155 // Make implicit type conversions explicit. 156 ::gogo->add_conversions(); 157 158 // Analyze the program flow for escape information. 159 ::gogo->analyze_escape(); 160 161 // Export global identifiers as appropriate. 162 ::gogo->do_exports(); 163 164 // Use temporary variables to force order of evaluation. 165 ::gogo->order_evaluations(); 166 167 // Turn short-cut operators (&&, ||) into explicit if statements. 168 ::gogo->remove_shortcuts(); 169 170 // Convert named types to backend representation. 171 ::gogo->convert_named_types(); 172 173 // Build thunks for functions which call recover. 174 ::gogo->build_recover_thunks(); 175 176 // Convert complicated go and defer statements into simpler ones. 177 ::gogo->simplify_thunk_statements(); 178 179 // Write out queued up functions for hash and comparison of types. 180 ::gogo->write_specific_type_functions(); 181 182 // Add write barriers. 183 ::gogo->add_write_barriers(); 184 185 // Flatten the parse tree. 186 ::gogo->flatten(); 187 188 // Reclaim memory of escape analysis Nodes. 189 ::gogo->reclaim_escape_nodes(); 190 191 // Dump ast, use filename[0] as the base name 192 ::gogo->dump_ast(filenames[0]); 193 } 194 195 // Write out globals. 196 197 GO_EXTERN_C 198 void 199 go_write_globals() 200 { 201 return ::gogo->write_globals(); 202 } 203 204 // Return the global IR structure. This is used by some of the 205 // langhooks to pass to other code. 206 207 Gogo* 208 go_get_gogo() 209 { 210 return ::gogo; 211 }