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