aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/gcc/go/gofrontend/go.cc
blob: 11692af8095ed96d8d0098d13c7cad158af9c19a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// go.cc -- Go frontend main file for gcc.

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-system.h"

#include "go-c.h"

#include "lex.h"
#include "parse.h"
#include "backend.h"
#include "gogo.h"

// The data structures we build to represent the file.
static Gogo* gogo;

// Create the main IR data structure.

GO_EXTERN_C
void
go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath,
	       const char *prefix, const char *relative_import_path)
{
  go_assert(::gogo == NULL);
  Linemap* linemap = go_get_linemap();
  ::gogo = new Gogo(go_get_backend(), linemap, int_type_size, pointer_size);

  if (pkgpath != NULL)
    ::gogo->set_pkgpath(pkgpath);
  else if (prefix != NULL)
    ::gogo->set_prefix(prefix);

  if (relative_import_path != NULL)
    ::gogo->set_relative_import_path(relative_import_path);

  // FIXME: This should be in the gcc dependent code.
  ::gogo->define_builtin_function_trees();
}

// Parse the input files.

GO_EXTERN_C
void
go_parse_input_files(const char** filenames, unsigned int filename_count,
		     bool only_check_syntax, bool require_return_statement)
{
  go_assert(filename_count > 0);

  for (unsigned int i = 0; i < filename_count; ++i)
    {
      if (i > 0)
	::gogo->clear_file_scope();

      const char* filename = filenames[i];
      FILE* file;
      if (strcmp(filename, "-") == 0)
	file = stdin;
      else
	{
	  file = fopen(filename, "r");
	  if (file == NULL)
	    fatal_error("cannot open %s: %m", filename);
	}

      Lex lexer(filename, file, ::gogo->linemap());

      Parse parse(&lexer, ::gogo);
      parse.program();

      if (strcmp(filename, "-") != 0)
	fclose(file);
    }

  ::gogo->linemap()->stop();

  ::gogo->clear_file_scope();

  // If the global predeclared names are referenced but not defined,
  // define them now.
  ::gogo->define_global_names();

  // Finalize method lists and build stub methods for named types.
  ::gogo->finalize_methods();

  // Now that we have seen all the names, lower the parse tree into a
  // form which is easier to use.
  ::gogo->lower_parse_tree();

  // Write out queued up functions for hash and comparison of types.
  ::gogo->write_specific_type_functions();

  // Now that we have seen all the names, verify that types are
  // correct.
  ::gogo->verify_types();

  // Work out types of unspecified constants and variables.
  ::gogo->determine_types();

  // Check types and issue errors as appropriate.
  ::gogo->check_types();

  if (only_check_syntax)
    return;

  // Check that functions have return statements.
  if (require_return_statement)
    ::gogo->check_return_statements();

  // Export global identifiers as appropriate.
  ::gogo->do_exports();

  // Turn short-cut operators (&&, ||) into explicit if statements.
  ::gogo->remove_shortcuts();

  // Use temporary variables to force order of evaluation.
  ::gogo->order_evaluations();

  // Build thunks for functions which call recover.
  ::gogo->build_recover_thunks();

  // Convert complicated go and defer statements into simpler ones.
  ::gogo->simplify_thunk_statements();
  
  // Dump ast, use filename[0] as the base name
  ::gogo->dump_ast(filenames[0]);
}

// Write out globals.

GO_EXTERN_C
void
go_write_globals()
{
  return ::gogo->write_globals();
}

// Return the global IR structure.  This is used by some of the
// langhooks to pass to other code.

Gogo*
go_get_gogo()
{
  return ::gogo;
}