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