mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 12:41:17 +08:00
2011-06-05 Jerry DeLisle <jvdelisle@gcc.gnu.org>
Merge trunk into branch, part one. [[Split portion of a mixed commit.]] From-SVN: r174658.2
This commit is contained in:
parent
419b55d0f9
commit
67f8f44952
12264
gcc/go/gofrontend/expressions.cc.merge-left.r167407
Normal file
12264
gcc/go/gofrontend/expressions.cc.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
12843
gcc/go/gofrontend/expressions.cc.merge-right.r172891
Normal file
12843
gcc/go/gofrontend/expressions.cc.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
12663
gcc/go/gofrontend/expressions.cc.working
Normal file
12663
gcc/go/gofrontend/expressions.cc.working
Normal file
File diff suppressed because it is too large
Load Diff
153
gcc/go/gofrontend/go.cc.merge-left.r167407
Normal file
153
gcc/go/gofrontend/go.cc.merge-left.r167407
Normal file
@ -0,0 +1,153 @@
|
||||
// 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 "gogo.h"
|
||||
|
||||
// The unique prefix to use for exported symbols. This is set during
|
||||
// option processing.
|
||||
|
||||
static std::string unique_prefix;
|
||||
|
||||
// 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 float_type_size, int pointer_size)
|
||||
{
|
||||
gcc_assert(::gogo == NULL);
|
||||
::gogo = new Gogo(int_type_size, float_type_size, pointer_size);
|
||||
if (!unique_prefix.empty())
|
||||
::gogo->set_unique_prefix(unique_prefix);
|
||||
}
|
||||
|
||||
// Set the unique prefix we use for exported symbols.
|
||||
|
||||
GO_EXTERN_C
|
||||
void
|
||||
go_set_prefix(const char* arg)
|
||||
{
|
||||
unique_prefix = arg;
|
||||
for (size_t i = 0; i < unique_prefix.length(); ++i)
|
||||
{
|
||||
char c = unique_prefix[i];
|
||||
if ((c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c >= '0' && c <= '9')
|
||||
|| c == '_')
|
||||
;
|
||||
else
|
||||
unique_prefix[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
gcc_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);
|
||||
|
||||
Parse parse(&lexer, ::gogo);
|
||||
parse.program();
|
||||
|
||||
if (strcmp(filename, "-") != 0)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
::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();
|
||||
|
||||
// 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();
|
||||
|
||||
// Build required interface method tables.
|
||||
::gogo->build_interface_method_tables();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
151
gcc/go/gofrontend/go.cc.merge-right.r172891
Normal file
151
gcc/go/gofrontend/go.cc.merge-right.r172891
Normal file
@ -0,0 +1,151 @@
|
||||
// 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 unique prefix to use for exported symbols. This is set during
|
||||
// option processing.
|
||||
|
||||
static std::string unique_prefix;
|
||||
|
||||
// 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)
|
||||
{
|
||||
go_assert(::gogo == NULL);
|
||||
::gogo = new Gogo(go_get_backend(), int_type_size, pointer_size);
|
||||
if (!unique_prefix.empty())
|
||||
::gogo->set_unique_prefix(unique_prefix);
|
||||
}
|
||||
|
||||
// Set the unique prefix we use for exported symbols.
|
||||
|
||||
GO_EXTERN_C
|
||||
void
|
||||
go_set_prefix(const char* arg)
|
||||
{
|
||||
unique_prefix = arg;
|
||||
for (size_t i = 0; i < unique_prefix.length(); ++i)
|
||||
{
|
||||
char c = unique_prefix[i];
|
||||
if ((c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c >= '0' && c <= '9')
|
||||
|| c == '_')
|
||||
;
|
||||
else
|
||||
unique_prefix[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
Parse parse(&lexer, ::gogo);
|
||||
parse.program();
|
||||
|
||||
if (strcmp(filename, "-") != 0)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
::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();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
150
gcc/go/gofrontend/go.cc.working
Normal file
150
gcc/go/gofrontend/go.cc.working
Normal file
@ -0,0 +1,150 @@
|
||||
// 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 "gogo.h"
|
||||
|
||||
// The unique prefix to use for exported symbols. This is set during
|
||||
// option processing.
|
||||
|
||||
static std::string unique_prefix;
|
||||
|
||||
// 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)
|
||||
{
|
||||
gcc_assert(::gogo == NULL);
|
||||
::gogo = new Gogo(int_type_size, pointer_size);
|
||||
if (!unique_prefix.empty())
|
||||
::gogo->set_unique_prefix(unique_prefix);
|
||||
}
|
||||
|
||||
// Set the unique prefix we use for exported symbols.
|
||||
|
||||
GO_EXTERN_C
|
||||
void
|
||||
go_set_prefix(const char* arg)
|
||||
{
|
||||
unique_prefix = arg;
|
||||
for (size_t i = 0; i < unique_prefix.length(); ++i)
|
||||
{
|
||||
char c = unique_prefix[i];
|
||||
if ((c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c >= '0' && c <= '9')
|
||||
|| c == '_')
|
||||
;
|
||||
else
|
||||
unique_prefix[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
gcc_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);
|
||||
|
||||
Parse parse(&lexer, ::gogo);
|
||||
parse.program();
|
||||
|
||||
if (strcmp(filename, "-") != 0)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
::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();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
3105
gcc/go/gofrontend/gogo-tree.cc.merge-left.r167407
Normal file
3105
gcc/go/gofrontend/gogo-tree.cc.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
2697
gcc/go/gofrontend/gogo-tree.cc.merge-right.r172891
Normal file
2697
gcc/go/gofrontend/gogo-tree.cc.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
3145
gcc/go/gofrontend/gogo-tree.cc.working
Normal file
3145
gcc/go/gofrontend/gogo-tree.cc.working
Normal file
File diff suppressed because it is too large
Load Diff
4274
gcc/go/gofrontend/gogo.cc.merge-left.r167407
Normal file
4274
gcc/go/gofrontend/gogo.cc.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
4796
gcc/go/gofrontend/gogo.cc.merge-right.r172891
Normal file
4796
gcc/go/gofrontend/gogo.cc.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
4514
gcc/go/gofrontend/gogo.cc.working
Normal file
4514
gcc/go/gofrontend/gogo.cc.working
Normal file
File diff suppressed because it is too large
Load Diff
2484
gcc/go/gofrontend/gogo.h.merge-left.r167407
Normal file
2484
gcc/go/gofrontend/gogo.h.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
2612
gcc/go/gofrontend/gogo.h.merge-right.r172891
Normal file
2612
gcc/go/gofrontend/gogo.h.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
2537
gcc/go/gofrontend/gogo.h.working
Normal file
2537
gcc/go/gofrontend/gogo.h.working
Normal file
File diff suppressed because it is too large
Load Diff
4730
gcc/go/gofrontend/parse.cc.merge-left.r167407
Normal file
4730
gcc/go/gofrontend/parse.cc.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
5131
gcc/go/gofrontend/parse.cc.merge-right.r172891
Normal file
5131
gcc/go/gofrontend/parse.cc.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
5015
gcc/go/gofrontend/parse.cc.working
Normal file
5015
gcc/go/gofrontend/parse.cc.working
Normal file
File diff suppressed because it is too large
Load Diff
307
gcc/go/gofrontend/parse.h.merge-left.r167407
Normal file
307
gcc/go/gofrontend/parse.h.merge-left.r167407
Normal file
@ -0,0 +1,307 @@
|
||||
// parse.h -- Go frontend parser. -*- C++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef GO_PARSE_H
|
||||
#define GO_PARSE_H
|
||||
|
||||
class Set_iota_traverse;
|
||||
class Lex;
|
||||
class Gogo;
|
||||
class Named_object;
|
||||
class Type;
|
||||
class Typed_identifier;
|
||||
class Typed_identifier_list;
|
||||
class Function_type;
|
||||
class Block;
|
||||
class Expression;
|
||||
class Expression_list;
|
||||
class Struct_field_list;
|
||||
class Case_clauses;
|
||||
class Type_case_clauses;
|
||||
class Select_clauses;
|
||||
class Statement;
|
||||
class Label;
|
||||
|
||||
// Parse the program.
|
||||
|
||||
class Parse
|
||||
{
|
||||
public:
|
||||
Parse(Lex*, Gogo*);
|
||||
|
||||
// Parse a program.
|
||||
void
|
||||
program();
|
||||
|
||||
private:
|
||||
// Precedence values.
|
||||
enum Precedence
|
||||
{
|
||||
PRECEDENCE_INVALID = -1,
|
||||
PRECEDENCE_NORMAL = 0,
|
||||
PRECEDENCE_OROR,
|
||||
PRECEDENCE_ANDAND,
|
||||
PRECEDENCE_CHANOP,
|
||||
PRECEDENCE_RELOP,
|
||||
PRECEDENCE_ADDOP,
|
||||
PRECEDENCE_MULOP
|
||||
};
|
||||
|
||||
// We use this when parsing the range clause of a for statement.
|
||||
struct Range_clause
|
||||
{
|
||||
// Set to true if we found a range clause.
|
||||
bool found;
|
||||
// The index expression.
|
||||
Expression* index;
|
||||
// The value expression.
|
||||
Expression* value;
|
||||
// The range expression.
|
||||
Expression* range;
|
||||
|
||||
Range_clause()
|
||||
: found(false), index(NULL), value(NULL), range(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
// We use this when parsing the statement at the start of a switch,
|
||||
// in order to recognize type switches.
|
||||
struct Type_switch
|
||||
{
|
||||
// Set to true if we find a type switch.
|
||||
bool found;
|
||||
// The variable name.
|
||||
std::string name;
|
||||
// The location of the variable.
|
||||
source_location location;
|
||||
// The expression.
|
||||
Expression* expr;
|
||||
|
||||
Type_switch()
|
||||
: found(false), name(), location(UNKNOWN_LOCATION), expr(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
// A variable defined in an enclosing function referenced by the
|
||||
// current function.
|
||||
class Enclosing_var
|
||||
{
|
||||
public:
|
||||
Enclosing_var(Named_object* var, Named_object* in_function,
|
||||
unsigned int index)
|
||||
: var_(var), in_function_(in_function), index_(index)
|
||||
{ }
|
||||
|
||||
// We put these in a vector, so we need a default constructor.
|
||||
Enclosing_var()
|
||||
: var_(NULL), in_function_(NULL), index_(-1U)
|
||||
{ }
|
||||
|
||||
Named_object*
|
||||
var() const
|
||||
{ return this->var_; }
|
||||
|
||||
Named_object*
|
||||
in_function() const
|
||||
{ return this->in_function_; }
|
||||
|
||||
unsigned int
|
||||
index() const
|
||||
{ return this->index_; }
|
||||
|
||||
private:
|
||||
// The variable which is being referred to.
|
||||
Named_object* var_;
|
||||
// The function where the variable is defined.
|
||||
Named_object* in_function_;
|
||||
// The index of the field in this function's closure struct for
|
||||
// this variable.
|
||||
unsigned int index_;
|
||||
};
|
||||
|
||||
// We store Enclosing_var entries in a set, so we need a comparator.
|
||||
struct Enclosing_var_comparison
|
||||
{
|
||||
bool
|
||||
operator()(const Enclosing_var&, const Enclosing_var&);
|
||||
};
|
||||
|
||||
// A set of Enclosing_var entries.
|
||||
typedef std::set<Enclosing_var, Enclosing_var_comparison> Enclosing_vars;
|
||||
|
||||
// Peek at the current token from the lexer.
|
||||
const Token*
|
||||
peek_token();
|
||||
|
||||
// Consume the current token, return the next one.
|
||||
const Token*
|
||||
advance_token();
|
||||
|
||||
// Push a token back on the input stream.
|
||||
void
|
||||
unget_token(const Token&);
|
||||
|
||||
// The location of the current token.
|
||||
source_location
|
||||
location();
|
||||
|
||||
// For break and continue we keep a stack of statements with
|
||||
// associated labels (if any). The top of the stack is used for a
|
||||
// break or continue statement with no label.
|
||||
typedef std::vector<std::pair<Statement*, const Label*> > Bc_stack;
|
||||
|
||||
// Parser nonterminals.
|
||||
void identifier_list(Typed_identifier_list*);
|
||||
Expression_list* expression_list(Expression*, bool may_be_sink);
|
||||
bool qualified_ident(std::string*, Named_object**);
|
||||
Type* type();
|
||||
bool type_may_start_here();
|
||||
Type* type_name(bool issue_error);
|
||||
Type* array_type(bool may_use_ellipsis);
|
||||
Type* map_type();
|
||||
Type* struct_type();
|
||||
void field_decl(Struct_field_list*);
|
||||
Type* pointer_type();
|
||||
Type* channel_type();
|
||||
Function_type* signature(Typed_identifier*, source_location);
|
||||
Typed_identifier_list* parameters(bool* is_varargs);
|
||||
Typed_identifier_list* parameter_list(bool* is_varargs);
|
||||
void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
|
||||
Typed_identifier_list* result();
|
||||
source_location block();
|
||||
Type* interface_type();
|
||||
bool method_spec(Typed_identifier_list*);
|
||||
void declaration();
|
||||
bool declaration_may_start_here();
|
||||
void decl(void (Parse::*)(void*), void*);
|
||||
void list(void (Parse::*)(void*), void*, bool);
|
||||
void const_decl();
|
||||
void const_spec(Type**, Expression_list**);
|
||||
void type_decl();
|
||||
void type_spec(void*);
|
||||
void var_decl();
|
||||
void var_spec(void*);
|
||||
void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_receive(const Typed_identifier_list*, Type*,
|
||||
Expression*, bool is_coloneq, source_location);
|
||||
bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
|
||||
Expression*, bool is_coloneq,
|
||||
source_location);
|
||||
Named_object* init_var(const Typed_identifier&, Type*, Expression*,
|
||||
bool is_coloneq, bool type_from_init, bool* is_new);
|
||||
void simple_var_decl_or_assignment(const std::string&, source_location,
|
||||
Range_clause*, Type_switch*);
|
||||
void function_decl();
|
||||
Typed_identifier* receiver();
|
||||
Expression* operand(bool may_be_sink);
|
||||
Expression* enclosing_var_reference(Named_object*, Named_object*,
|
||||
source_location);
|
||||
Expression* composite_lit(Type*, int depth, source_location);
|
||||
Expression* function_lit();
|
||||
Expression* create_closure(Named_object* function, Enclosing_vars*,
|
||||
source_location);
|
||||
Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
|
||||
bool* is_type_switch);
|
||||
Expression* selector(Expression*, bool* is_type_switch);
|
||||
Expression* index(Expression*);
|
||||
Expression* call(Expression*);
|
||||
Expression* expression(Precedence, bool may_be_sink,
|
||||
bool may_be_composite_lit, bool* is_type_switch);
|
||||
bool expression_may_start_here();
|
||||
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
|
||||
bool* is_type_switch);
|
||||
Expression* qualified_expr(Expression*, source_location);
|
||||
Expression* id_to_expression(const std::string&, source_location);
|
||||
void statement(const Label*);
|
||||
bool statement_may_start_here();
|
||||
void labeled_stmt(const std::string&, source_location);
|
||||
Expression* simple_stat(bool, bool, Range_clause*, Type_switch*);
|
||||
bool simple_stat_may_start_here();
|
||||
void statement_list();
|
||||
bool statement_list_may_start_here();
|
||||
void expression_stat(Expression*);
|
||||
void inc_dec_stat(Expression*);
|
||||
void assignment(Expression*, Range_clause*);
|
||||
void tuple_assignment(Expression_list*, Range_clause*);
|
||||
void send();
|
||||
void go_or_defer_stat();
|
||||
void return_stat();
|
||||
void if_stat();
|
||||
void switch_stat(const Label*);
|
||||
Statement* expr_switch_body(const Label*, Expression*, source_location);
|
||||
void expr_case_clause(Case_clauses*);
|
||||
Expression_list* expr_switch_case(bool*);
|
||||
Statement* type_switch_body(const Label*, const Type_switch&,
|
||||
source_location);
|
||||
void type_case_clause(Named_object*, Type_case_clauses*);
|
||||
void type_switch_case(std::vector<Type*>*, bool*);
|
||||
void select_stat(const Label*);
|
||||
void comm_clause(Select_clauses*);
|
||||
bool comm_case(bool*, Expression**, Expression**, std::string*, bool*);
|
||||
bool send_or_recv_expr(bool*, Expression**, Expression**, std::string*);
|
||||
void for_stat(const Label*);
|
||||
void for_clause(Expression**, Block**);
|
||||
void range_clause_decl(const Typed_identifier_list*, Range_clause*);
|
||||
void range_clause_expr(const Expression_list*, Range_clause*);
|
||||
void push_break_statement(Statement*, const Label*);
|
||||
void push_continue_statement(Statement*, const Label*);
|
||||
void pop_break_statement();
|
||||
void pop_continue_statement();
|
||||
Statement* find_bc_statement(const Bc_stack*, const std::string&);
|
||||
void break_stat();
|
||||
void continue_stat();
|
||||
void goto_stat();
|
||||
void package_clause();
|
||||
void import_decl();
|
||||
void import_spec(void*);
|
||||
|
||||
void reset_iota();
|
||||
int iota_value();
|
||||
void increment_iota();
|
||||
|
||||
// Skip past an error looking for a semicolon or OP. Return true if
|
||||
// all is well, false if we found EOF.
|
||||
bool
|
||||
skip_past_error(Operator op);
|
||||
|
||||
// Verify that an expression is not a sink, and return either the
|
||||
// expression or an error.
|
||||
Expression*
|
||||
verify_not_sink(Expression*);
|
||||
|
||||
// Return the statement associated with a label in a Bc_stack, or
|
||||
// NULL.
|
||||
Statement*
|
||||
find_bc_statement(const Bc_stack*, const std::string&) const;
|
||||
|
||||
// The lexer output we are parsing.
|
||||
Lex* lex_;
|
||||
// The current token.
|
||||
Token token_;
|
||||
// A token pushed back on the input stream.
|
||||
Token unget_token_;
|
||||
// Whether unget_token_ is valid.
|
||||
bool unget_token_valid_;
|
||||
// The code we are generating.
|
||||
Gogo* gogo_;
|
||||
// A stack of statements for which break may be used.
|
||||
Bc_stack break_stack_;
|
||||
// A stack of statements for which continue may be used.
|
||||
Bc_stack continue_stack_;
|
||||
// The current iota value.
|
||||
int iota_;
|
||||
// References from the local function to variables defined in
|
||||
// enclosing functions.
|
||||
Enclosing_vars enclosing_vars_;
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(GO_PARSE_H)
|
309
gcc/go/gofrontend/parse.h.merge-right.r172891
Normal file
309
gcc/go/gofrontend/parse.h.merge-right.r172891
Normal file
@ -0,0 +1,309 @@
|
||||
// parse.h -- Go frontend parser. -*- C++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef GO_PARSE_H
|
||||
#define GO_PARSE_H
|
||||
|
||||
class Set_iota_traverse;
|
||||
class Lex;
|
||||
class Gogo;
|
||||
class Named_object;
|
||||
class Type;
|
||||
class Typed_identifier;
|
||||
class Typed_identifier_list;
|
||||
class Function_type;
|
||||
class Block;
|
||||
class Expression;
|
||||
class Expression_list;
|
||||
class Struct_field_list;
|
||||
class Case_clauses;
|
||||
class Type_case_clauses;
|
||||
class Select_clauses;
|
||||
class Statement;
|
||||
class Label;
|
||||
|
||||
// Parse the program.
|
||||
|
||||
class Parse
|
||||
{
|
||||
public:
|
||||
Parse(Lex*, Gogo*);
|
||||
|
||||
// Parse a program.
|
||||
void
|
||||
program();
|
||||
|
||||
private:
|
||||
// Precedence values.
|
||||
enum Precedence
|
||||
{
|
||||
PRECEDENCE_INVALID = -1,
|
||||
PRECEDENCE_NORMAL = 0,
|
||||
PRECEDENCE_OROR,
|
||||
PRECEDENCE_ANDAND,
|
||||
PRECEDENCE_RELOP,
|
||||
PRECEDENCE_ADDOP,
|
||||
PRECEDENCE_MULOP
|
||||
};
|
||||
|
||||
// We use this when parsing the range clause of a for statement.
|
||||
struct Range_clause
|
||||
{
|
||||
// Set to true if we found a range clause.
|
||||
bool found;
|
||||
// The index expression.
|
||||
Expression* index;
|
||||
// The value expression.
|
||||
Expression* value;
|
||||
// The range expression.
|
||||
Expression* range;
|
||||
|
||||
Range_clause()
|
||||
: found(false), index(NULL), value(NULL), range(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
// We use this when parsing the statement at the start of a switch,
|
||||
// in order to recognize type switches.
|
||||
struct Type_switch
|
||||
{
|
||||
// Set to true if we find a type switch.
|
||||
bool found;
|
||||
// The variable name.
|
||||
std::string name;
|
||||
// The location of the variable.
|
||||
source_location location;
|
||||
// The expression.
|
||||
Expression* expr;
|
||||
|
||||
Type_switch()
|
||||
: found(false), name(), location(UNKNOWN_LOCATION), expr(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
// A variable defined in an enclosing function referenced by the
|
||||
// current function.
|
||||
class Enclosing_var
|
||||
{
|
||||
public:
|
||||
Enclosing_var(Named_object* var, Named_object* in_function,
|
||||
unsigned int index)
|
||||
: var_(var), in_function_(in_function), index_(index)
|
||||
{ }
|
||||
|
||||
// We put these in a vector, so we need a default constructor.
|
||||
Enclosing_var()
|
||||
: var_(NULL), in_function_(NULL), index_(-1U)
|
||||
{ }
|
||||
|
||||
Named_object*
|
||||
var() const
|
||||
{ return this->var_; }
|
||||
|
||||
Named_object*
|
||||
in_function() const
|
||||
{ return this->in_function_; }
|
||||
|
||||
unsigned int
|
||||
index() const
|
||||
{ return this->index_; }
|
||||
|
||||
private:
|
||||
// The variable which is being referred to.
|
||||
Named_object* var_;
|
||||
// The function where the variable is defined.
|
||||
Named_object* in_function_;
|
||||
// The index of the field in this function's closure struct for
|
||||
// this variable.
|
||||
unsigned int index_;
|
||||
};
|
||||
|
||||
// We store Enclosing_var entries in a set, so we need a comparator.
|
||||
struct Enclosing_var_comparison
|
||||
{
|
||||
bool
|
||||
operator()(const Enclosing_var&, const Enclosing_var&);
|
||||
};
|
||||
|
||||
// A set of Enclosing_var entries.
|
||||
typedef std::set<Enclosing_var, Enclosing_var_comparison> Enclosing_vars;
|
||||
|
||||
// Peek at the current token from the lexer.
|
||||
const Token*
|
||||
peek_token();
|
||||
|
||||
// Consume the current token, return the next one.
|
||||
const Token*
|
||||
advance_token();
|
||||
|
||||
// Push a token back on the input stream.
|
||||
void
|
||||
unget_token(const Token&);
|
||||
|
||||
// The location of the current token.
|
||||
source_location
|
||||
location();
|
||||
|
||||
// For break and continue we keep a stack of statements with
|
||||
// associated labels (if any). The top of the stack is used for a
|
||||
// break or continue statement with no label.
|
||||
typedef std::vector<std::pair<Statement*, Label*> > Bc_stack;
|
||||
|
||||
// Parser nonterminals.
|
||||
void identifier_list(Typed_identifier_list*);
|
||||
Expression_list* expression_list(Expression*, bool may_be_sink);
|
||||
bool qualified_ident(std::string*, Named_object**);
|
||||
Type* type();
|
||||
bool type_may_start_here();
|
||||
Type* type_name(bool issue_error);
|
||||
Type* array_type(bool may_use_ellipsis);
|
||||
Type* map_type();
|
||||
Type* struct_type();
|
||||
void field_decl(Struct_field_list*);
|
||||
Type* pointer_type();
|
||||
Type* channel_type();
|
||||
Function_type* signature(Typed_identifier*, source_location);
|
||||
bool parameters(Typed_identifier_list**, bool* is_varargs);
|
||||
Typed_identifier_list* parameter_list(bool* is_varargs);
|
||||
void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
|
||||
bool result(Typed_identifier_list**);
|
||||
source_location block();
|
||||
Type* interface_type();
|
||||
void method_spec(Typed_identifier_list*);
|
||||
void declaration();
|
||||
bool declaration_may_start_here();
|
||||
void decl(void (Parse::*)(void*), void*);
|
||||
void list(void (Parse::*)(void*), void*, bool);
|
||||
void const_decl();
|
||||
void const_spec(Type**, Expression_list**);
|
||||
void type_decl();
|
||||
void type_spec(void*);
|
||||
void var_decl();
|
||||
void var_spec(void*);
|
||||
void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_receive(const Typed_identifier_list*, Type*,
|
||||
Expression*, bool is_coloneq, source_location);
|
||||
bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
|
||||
Expression*, bool is_coloneq,
|
||||
source_location);
|
||||
Named_object* init_var(const Typed_identifier&, Type*, Expression*,
|
||||
bool is_coloneq, bool type_from_init, bool* is_new);
|
||||
Named_object* create_dummy_global(Type*, Expression*, source_location);
|
||||
void simple_var_decl_or_assignment(const std::string&, source_location,
|
||||
Range_clause*, Type_switch*);
|
||||
void function_decl();
|
||||
Typed_identifier* receiver();
|
||||
Expression* operand(bool may_be_sink);
|
||||
Expression* enclosing_var_reference(Named_object*, Named_object*,
|
||||
source_location);
|
||||
Expression* composite_lit(Type*, int depth, source_location);
|
||||
Expression* function_lit();
|
||||
Expression* create_closure(Named_object* function, Enclosing_vars*,
|
||||
source_location);
|
||||
Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
|
||||
bool* is_type_switch);
|
||||
Expression* selector(Expression*, bool* is_type_switch);
|
||||
Expression* index(Expression*);
|
||||
Expression* call(Expression*);
|
||||
Expression* expression(Precedence, bool may_be_sink,
|
||||
bool may_be_composite_lit, bool* is_type_switch);
|
||||
bool expression_may_start_here();
|
||||
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
|
||||
bool* is_type_switch);
|
||||
Expression* qualified_expr(Expression*, source_location);
|
||||
Expression* id_to_expression(const std::string&, source_location);
|
||||
void statement(Label*);
|
||||
bool statement_may_start_here();
|
||||
void labeled_stmt(const std::string&, source_location);
|
||||
Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*);
|
||||
bool simple_stat_may_start_here();
|
||||
void statement_list();
|
||||
bool statement_list_may_start_here();
|
||||
void expression_stat(Expression*);
|
||||
void send_stmt(Expression*);
|
||||
void inc_dec_stat(Expression*);
|
||||
void assignment(Expression*, Range_clause*);
|
||||
void tuple_assignment(Expression_list*, Range_clause*);
|
||||
void send();
|
||||
void go_or_defer_stat();
|
||||
void return_stat();
|
||||
void if_stat();
|
||||
void switch_stat(Label*);
|
||||
Statement* expr_switch_body(Label*, Expression*, source_location);
|
||||
void expr_case_clause(Case_clauses*, bool* saw_default);
|
||||
Expression_list* expr_switch_case(bool*);
|
||||
Statement* type_switch_body(Label*, const Type_switch&, source_location);
|
||||
void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default);
|
||||
void type_switch_case(std::vector<Type*>*, bool*);
|
||||
void select_stat(Label*);
|
||||
void comm_clause(Select_clauses*, bool* saw_default);
|
||||
bool comm_case(bool*, Expression**, Expression**, Expression**,
|
||||
std::string*, std::string*, bool*);
|
||||
bool send_or_recv_stmt(bool*, Expression**, Expression**, Expression**,
|
||||
std::string*, std::string*);
|
||||
void for_stat(Label*);
|
||||
void for_clause(Expression**, Block**);
|
||||
void range_clause_decl(const Typed_identifier_list*, Range_clause*);
|
||||
void range_clause_expr(const Expression_list*, Range_clause*);
|
||||
void push_break_statement(Statement*, Label*);
|
||||
void push_continue_statement(Statement*, Label*);
|
||||
void pop_break_statement();
|
||||
void pop_continue_statement();
|
||||
Statement* find_bc_statement(const Bc_stack*, const std::string&);
|
||||
void break_stat();
|
||||
void continue_stat();
|
||||
void goto_stat();
|
||||
void package_clause();
|
||||
void import_decl();
|
||||
void import_spec(void*);
|
||||
|
||||
void reset_iota();
|
||||
int iota_value();
|
||||
void increment_iota();
|
||||
|
||||
// Skip past an error looking for a semicolon or OP. Return true if
|
||||
// all is well, false if we found EOF.
|
||||
bool
|
||||
skip_past_error(Operator op);
|
||||
|
||||
// Verify that an expression is not a sink, and return either the
|
||||
// expression or an error.
|
||||
Expression*
|
||||
verify_not_sink(Expression*);
|
||||
|
||||
// Return the statement associated with a label in a Bc_stack, or
|
||||
// NULL.
|
||||
Statement*
|
||||
find_bc_statement(const Bc_stack*, const std::string&) const;
|
||||
|
||||
// The lexer output we are parsing.
|
||||
Lex* lex_;
|
||||
// The current token.
|
||||
Token token_;
|
||||
// A token pushed back on the input stream.
|
||||
Token unget_token_;
|
||||
// Whether unget_token_ is valid.
|
||||
bool unget_token_valid_;
|
||||
// The code we are generating.
|
||||
Gogo* gogo_;
|
||||
// A stack of statements for which break may be used.
|
||||
Bc_stack* break_stack_;
|
||||
// A stack of statements for which continue may be used.
|
||||
Bc_stack* continue_stack_;
|
||||
// The current iota value.
|
||||
int iota_;
|
||||
// References from the local function to variables defined in
|
||||
// enclosing functions.
|
||||
Enclosing_vars enclosing_vars_;
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(GO_PARSE_H)
|
310
gcc/go/gofrontend/parse.h.working
Normal file
310
gcc/go/gofrontend/parse.h.working
Normal file
@ -0,0 +1,310 @@
|
||||
// parse.h -- Go frontend parser. -*- C++ -*-
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef GO_PARSE_H
|
||||
#define GO_PARSE_H
|
||||
|
||||
class Set_iota_traverse;
|
||||
class Lex;
|
||||
class Gogo;
|
||||
class Named_object;
|
||||
class Type;
|
||||
class Typed_identifier;
|
||||
class Typed_identifier_list;
|
||||
class Function_type;
|
||||
class Block;
|
||||
class Expression;
|
||||
class Expression_list;
|
||||
class Struct_field_list;
|
||||
class Case_clauses;
|
||||
class Type_case_clauses;
|
||||
class Select_clauses;
|
||||
class Statement;
|
||||
class Label;
|
||||
|
||||
// Parse the program.
|
||||
|
||||
class Parse
|
||||
{
|
||||
public:
|
||||
Parse(Lex*, Gogo*);
|
||||
|
||||
// Parse a program.
|
||||
void
|
||||
program();
|
||||
|
||||
private:
|
||||
// Precedence values.
|
||||
enum Precedence
|
||||
{
|
||||
PRECEDENCE_INVALID = -1,
|
||||
PRECEDENCE_NORMAL = 0,
|
||||
PRECEDENCE_OROR,
|
||||
PRECEDENCE_ANDAND,
|
||||
PRECEDENCE_RELOP,
|
||||
PRECEDENCE_ADDOP,
|
||||
PRECEDENCE_MULOP
|
||||
};
|
||||
|
||||
// We use this when parsing the range clause of a for statement.
|
||||
struct Range_clause
|
||||
{
|
||||
// Set to true if we found a range clause.
|
||||
bool found;
|
||||
// The index expression.
|
||||
Expression* index;
|
||||
// The value expression.
|
||||
Expression* value;
|
||||
// The range expression.
|
||||
Expression* range;
|
||||
|
||||
Range_clause()
|
||||
: found(false), index(NULL), value(NULL), range(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
// We use this when parsing the statement at the start of a switch,
|
||||
// in order to recognize type switches.
|
||||
struct Type_switch
|
||||
{
|
||||
// Set to true if we find a type switch.
|
||||
bool found;
|
||||
// The variable name.
|
||||
std::string name;
|
||||
// The location of the variable.
|
||||
source_location location;
|
||||
// The expression.
|
||||
Expression* expr;
|
||||
|
||||
Type_switch()
|
||||
: found(false), name(), location(UNKNOWN_LOCATION), expr(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
// A variable defined in an enclosing function referenced by the
|
||||
// current function.
|
||||
class Enclosing_var
|
||||
{
|
||||
public:
|
||||
Enclosing_var(Named_object* var, Named_object* in_function,
|
||||
unsigned int index)
|
||||
: var_(var), in_function_(in_function), index_(index)
|
||||
{ }
|
||||
|
||||
// We put these in a vector, so we need a default constructor.
|
||||
Enclosing_var()
|
||||
: var_(NULL), in_function_(NULL), index_(-1U)
|
||||
{ }
|
||||
|
||||
Named_object*
|
||||
var() const
|
||||
{ return this->var_; }
|
||||
|
||||
Named_object*
|
||||
in_function() const
|
||||
{ return this->in_function_; }
|
||||
|
||||
unsigned int
|
||||
index() const
|
||||
{ return this->index_; }
|
||||
|
||||
private:
|
||||
// The variable which is being referred to.
|
||||
Named_object* var_;
|
||||
// The function where the variable is defined.
|
||||
Named_object* in_function_;
|
||||
// The index of the field in this function's closure struct for
|
||||
// this variable.
|
||||
unsigned int index_;
|
||||
};
|
||||
|
||||
// We store Enclosing_var entries in a set, so we need a comparator.
|
||||
struct Enclosing_var_comparison
|
||||
{
|
||||
bool
|
||||
operator()(const Enclosing_var&, const Enclosing_var&);
|
||||
};
|
||||
|
||||
// A set of Enclosing_var entries.
|
||||
typedef std::set<Enclosing_var, Enclosing_var_comparison> Enclosing_vars;
|
||||
|
||||
// Peek at the current token from the lexer.
|
||||
const Token*
|
||||
peek_token();
|
||||
|
||||
// Consume the current token, return the next one.
|
||||
const Token*
|
||||
advance_token();
|
||||
|
||||
// Push a token back on the input stream.
|
||||
void
|
||||
unget_token(const Token&);
|
||||
|
||||
// The location of the current token.
|
||||
source_location
|
||||
location();
|
||||
|
||||
// For break and continue we keep a stack of statements with
|
||||
// associated labels (if any). The top of the stack is used for a
|
||||
// break or continue statement with no label.
|
||||
typedef std::vector<std::pair<Statement*, const Label*> > Bc_stack;
|
||||
|
||||
// Parser nonterminals.
|
||||
void identifier_list(Typed_identifier_list*);
|
||||
Expression_list* expression_list(Expression*, bool may_be_sink);
|
||||
bool qualified_ident(std::string*, Named_object**);
|
||||
Type* type();
|
||||
bool type_may_start_here();
|
||||
Type* type_name(bool issue_error);
|
||||
Type* array_type(bool may_use_ellipsis);
|
||||
Type* map_type();
|
||||
Type* struct_type();
|
||||
void field_decl(Struct_field_list*);
|
||||
Type* pointer_type();
|
||||
Type* channel_type();
|
||||
Function_type* signature(Typed_identifier*, source_location);
|
||||
bool parameters(Typed_identifier_list**, bool* is_varargs);
|
||||
Typed_identifier_list* parameter_list(bool* is_varargs);
|
||||
void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
|
||||
bool result(Typed_identifier_list**);
|
||||
source_location block();
|
||||
Type* interface_type();
|
||||
void method_spec(Typed_identifier_list*);
|
||||
void declaration();
|
||||
bool declaration_may_start_here();
|
||||
void decl(void (Parse::*)(void*), void*);
|
||||
void list(void (Parse::*)(void*), void*, bool);
|
||||
void const_decl();
|
||||
void const_spec(Type**, Expression_list**);
|
||||
void type_decl();
|
||||
void type_spec(void*);
|
||||
void var_decl();
|
||||
void var_spec(void*);
|
||||
void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
|
||||
bool is_coloneq, source_location);
|
||||
bool init_vars_from_receive(const Typed_identifier_list*, Type*,
|
||||
Expression*, bool is_coloneq, source_location);
|
||||
bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
|
||||
Expression*, bool is_coloneq,
|
||||
source_location);
|
||||
Named_object* init_var(const Typed_identifier&, Type*, Expression*,
|
||||
bool is_coloneq, bool type_from_init, bool* is_new);
|
||||
Named_object* create_dummy_global(Type*, Expression*, source_location);
|
||||
void simple_var_decl_or_assignment(const std::string&, source_location,
|
||||
Range_clause*, Type_switch*);
|
||||
void function_decl();
|
||||
Typed_identifier* receiver();
|
||||
Expression* operand(bool may_be_sink);
|
||||
Expression* enclosing_var_reference(Named_object*, Named_object*,
|
||||
source_location);
|
||||
Expression* composite_lit(Type*, int depth, source_location);
|
||||
Expression* function_lit();
|
||||
Expression* create_closure(Named_object* function, Enclosing_vars*,
|
||||
source_location);
|
||||
Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
|
||||
bool* is_type_switch);
|
||||
Expression* selector(Expression*, bool* is_type_switch);
|
||||
Expression* index(Expression*);
|
||||
Expression* call(Expression*);
|
||||
Expression* expression(Precedence, bool may_be_sink,
|
||||
bool may_be_composite_lit, bool* is_type_switch);
|
||||
bool expression_may_start_here();
|
||||
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
|
||||
bool* is_type_switch);
|
||||
Expression* qualified_expr(Expression*, source_location);
|
||||
Expression* id_to_expression(const std::string&, source_location);
|
||||
void statement(const Label*);
|
||||
bool statement_may_start_here();
|
||||
void labeled_stmt(const std::string&, source_location);
|
||||
Expression* simple_stat(bool, bool, Range_clause*, Type_switch*);
|
||||
bool simple_stat_may_start_here();
|
||||
void statement_list();
|
||||
bool statement_list_may_start_here();
|
||||
void expression_stat(Expression*);
|
||||
void send_stmt(Expression*);
|
||||
void inc_dec_stat(Expression*);
|
||||
void assignment(Expression*, Range_clause*);
|
||||
void tuple_assignment(Expression_list*, Range_clause*);
|
||||
void send();
|
||||
void go_or_defer_stat();
|
||||
void return_stat();
|
||||
void if_stat();
|
||||
void switch_stat(const Label*);
|
||||
Statement* expr_switch_body(const Label*, Expression*, source_location);
|
||||
void expr_case_clause(Case_clauses*, bool* saw_default);
|
||||
Expression_list* expr_switch_case(bool*);
|
||||
Statement* type_switch_body(const Label*, const Type_switch&,
|
||||
source_location);
|
||||
void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default);
|
||||
void type_switch_case(std::vector<Type*>*, bool*);
|
||||
void select_stat(const Label*);
|
||||
void comm_clause(Select_clauses*, bool* saw_default);
|
||||
bool comm_case(bool*, Expression**, Expression**, Expression**,
|
||||
std::string*, std::string*, bool*);
|
||||
bool send_or_recv_stmt(bool*, Expression**, Expression**, Expression**,
|
||||
std::string*, std::string*);
|
||||
void for_stat(const Label*);
|
||||
void for_clause(Expression**, Block**);
|
||||
void range_clause_decl(const Typed_identifier_list*, Range_clause*);
|
||||
void range_clause_expr(const Expression_list*, Range_clause*);
|
||||
void push_break_statement(Statement*, const Label*);
|
||||
void push_continue_statement(Statement*, const Label*);
|
||||
void pop_break_statement();
|
||||
void pop_continue_statement();
|
||||
Statement* find_bc_statement(const Bc_stack*, const std::string&);
|
||||
void break_stat();
|
||||
void continue_stat();
|
||||
void goto_stat();
|
||||
void package_clause();
|
||||
void import_decl();
|
||||
void import_spec(void*);
|
||||
|
||||
void reset_iota();
|
||||
int iota_value();
|
||||
void increment_iota();
|
||||
|
||||
// Skip past an error looking for a semicolon or OP. Return true if
|
||||
// all is well, false if we found EOF.
|
||||
bool
|
||||
skip_past_error(Operator op);
|
||||
|
||||
// Verify that an expression is not a sink, and return either the
|
||||
// expression or an error.
|
||||
Expression*
|
||||
verify_not_sink(Expression*);
|
||||
|
||||
// Return the statement associated with a label in a Bc_stack, or
|
||||
// NULL.
|
||||
Statement*
|
||||
find_bc_statement(const Bc_stack*, const std::string&) const;
|
||||
|
||||
// The lexer output we are parsing.
|
||||
Lex* lex_;
|
||||
// The current token.
|
||||
Token token_;
|
||||
// A token pushed back on the input stream.
|
||||
Token unget_token_;
|
||||
// Whether unget_token_ is valid.
|
||||
bool unget_token_valid_;
|
||||
// The code we are generating.
|
||||
Gogo* gogo_;
|
||||
// A stack of statements for which break may be used.
|
||||
Bc_stack* break_stack_;
|
||||
// A stack of statements for which continue may be used.
|
||||
Bc_stack* continue_stack_;
|
||||
// The current iota value.
|
||||
int iota_;
|
||||
// References from the local function to variables defined in
|
||||
// enclosing functions.
|
||||
Enclosing_vars enclosing_vars_;
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(GO_PARSE_H)
|
5146
gcc/go/gofrontend/statements.cc.merge-left.r167407
Normal file
5146
gcc/go/gofrontend/statements.cc.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
5073
gcc/go/gofrontend/statements.cc.merge-right.r172891
Normal file
5073
gcc/go/gofrontend/statements.cc.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
5396
gcc/go/gofrontend/statements.cc.working
Normal file
5396
gcc/go/gofrontend/statements.cc.working
Normal file
File diff suppressed because it is too large
Load Diff
1420
gcc/go/gofrontend/statements.h.merge-left.r167407
Normal file
1420
gcc/go/gofrontend/statements.h.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
1446
gcc/go/gofrontend/statements.h.merge-right.r172891
Normal file
1446
gcc/go/gofrontend/statements.h.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
1461
gcc/go/gofrontend/statements.h.working
Normal file
1461
gcc/go/gofrontend/statements.h.working
Normal file
File diff suppressed because it is too large
Load Diff
8078
gcc/go/gofrontend/types.cc.merge-left.r167407
Normal file
8078
gcc/go/gofrontend/types.cc.merge-left.r167407
Normal file
File diff suppressed because it is too large
Load Diff
8676
gcc/go/gofrontend/types.cc.merge-right.r172891
Normal file
8676
gcc/go/gofrontend/types.cc.merge-right.r172891
Normal file
File diff suppressed because it is too large
Load Diff
8656
gcc/go/gofrontend/types.cc.working
Normal file
8656
gcc/go/gofrontend/types.cc.working
Normal file
File diff suppressed because it is too large
Load Diff
134
gcc/go/gofrontend/unsafe.cc.merge-left.r167407
Normal file
134
gcc/go/gofrontend/unsafe.cc.merge-left.r167407
Normal file
@ -0,0 +1,134 @@
|
||||
// unsafe.cc -- Go frontend builtin unsafe package.
|
||||
|
||||
// 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 "types.h"
|
||||
#include "gogo.h"
|
||||
|
||||
// Set up the builtin unsafe package. This should probably be driven
|
||||
// by a table.
|
||||
|
||||
void
|
||||
Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
|
||||
source_location location)
|
||||
{
|
||||
location_t bloc = BUILTINS_LOCATION;
|
||||
|
||||
bool add_to_globals;
|
||||
Package* package = this->add_imported_package("unsafe", local_name,
|
||||
is_local_name_exported,
|
||||
"libgo_unsafe",
|
||||
location, &add_to_globals);
|
||||
package->set_is_imported();
|
||||
|
||||
Bindings* bindings = package->bindings();
|
||||
|
||||
// The type may have already been created by an import.
|
||||
Named_object* no = package->bindings()->lookup("Pointer");
|
||||
if (no == NULL)
|
||||
{
|
||||
Type* type = Type::make_pointer_type(Type::make_void_type());
|
||||
no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert(no->package() == package);
|
||||
gcc_assert(no->is_type());
|
||||
gcc_assert(no->type_value()->is_unsafe_pointer_type());
|
||||
no->type_value()->set_is_visible();
|
||||
}
|
||||
Named_type* pointer_type = no->type_value();
|
||||
if (add_to_globals)
|
||||
this->add_named_type(pointer_type);
|
||||
|
||||
Type* int_type = this->lookup_global("int")->type_value();
|
||||
|
||||
// Sizeof.
|
||||
Typed_identifier_list* results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Offsetof.
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_varargs();
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Alignof.
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_varargs();
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Typeof.
|
||||
Type* empty_interface = Type::make_interface_type(NULL, bloc);
|
||||
Typed_identifier_list* parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("i", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Typeof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Reflect.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("it", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Reflect", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Unreflect.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
parameters->push_back(Typed_identifier("addr", pointer_type, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Unreflect", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// New.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("New", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// NewArray.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
parameters->push_back(Typed_identifier("n", int_type, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("NewArray", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
this->imported_unsafe_ = true;
|
||||
}
|
146
gcc/go/gofrontend/unsafe.cc.merge-right.r172891
Normal file
146
gcc/go/gofrontend/unsafe.cc.merge-right.r172891
Normal file
@ -0,0 +1,146 @@
|
||||
// unsafe.cc -- Go frontend builtin unsafe package.
|
||||
|
||||
// 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 "types.h"
|
||||
#include "gogo.h"
|
||||
|
||||
// Set up the builtin unsafe package. This should probably be driven
|
||||
// by a table.
|
||||
|
||||
void
|
||||
Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
|
||||
source_location location)
|
||||
{
|
||||
location_t bloc = BUILTINS_LOCATION;
|
||||
|
||||
bool add_to_globals;
|
||||
Package* package = this->add_imported_package("unsafe", local_name,
|
||||
is_local_name_exported,
|
||||
"libgo_unsafe",
|
||||
location, &add_to_globals);
|
||||
|
||||
if (package == NULL)
|
||||
{
|
||||
go_assert(saw_errors());
|
||||
return;
|
||||
}
|
||||
|
||||
package->set_is_imported();
|
||||
|
||||
Bindings* bindings = package->bindings();
|
||||
|
||||
// The type may have already been created by an import.
|
||||
Named_object* no = package->bindings()->lookup("Pointer");
|
||||
if (no == NULL)
|
||||
{
|
||||
Type* type = Type::make_pointer_type(Type::make_void_type());
|
||||
no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
go_assert(no->package() == package);
|
||||
go_assert(no->is_type());
|
||||
go_assert(no->type_value()->is_unsafe_pointer_type());
|
||||
no->type_value()->set_is_visible();
|
||||
}
|
||||
Named_type* pointer_type = no->type_value();
|
||||
if (add_to_globals)
|
||||
this->add_named_type(pointer_type);
|
||||
|
||||
Type* int_type = this->lookup_global("int")->type_value();
|
||||
|
||||
// Sizeof.
|
||||
Typed_identifier_list* results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Offsetof.
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_varargs();
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Alignof.
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_varargs();
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Typeof.
|
||||
Type* empty_interface = Type::make_interface_type(NULL, bloc);
|
||||
Typed_identifier_list* parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("i", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Typeof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Reflect.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("it", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Reflect", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Unreflect.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
parameters->push_back(Typed_identifier("addr", pointer_type, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Unreflect", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// New.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("New", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// NewArray.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
parameters->push_back(Typed_identifier("n", int_type, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("NewArray", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
if (!this->imported_unsafe_)
|
||||
{
|
||||
go_imported_unsafe();
|
||||
this->imported_unsafe_ = true;
|
||||
}
|
||||
}
|
146
gcc/go/gofrontend/unsafe.cc.working
Normal file
146
gcc/go/gofrontend/unsafe.cc.working
Normal file
@ -0,0 +1,146 @@
|
||||
// unsafe.cc -- Go frontend builtin unsafe package.
|
||||
|
||||
// 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 "types.h"
|
||||
#include "gogo.h"
|
||||
|
||||
// Set up the builtin unsafe package. This should probably be driven
|
||||
// by a table.
|
||||
|
||||
void
|
||||
Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
|
||||
source_location location)
|
||||
{
|
||||
location_t bloc = BUILTINS_LOCATION;
|
||||
|
||||
bool add_to_globals;
|
||||
Package* package = this->add_imported_package("unsafe", local_name,
|
||||
is_local_name_exported,
|
||||
"libgo_unsafe",
|
||||
location, &add_to_globals);
|
||||
|
||||
if (package == NULL)
|
||||
{
|
||||
gcc_assert(saw_errors());
|
||||
return;
|
||||
}
|
||||
|
||||
package->set_is_imported();
|
||||
|
||||
Bindings* bindings = package->bindings();
|
||||
|
||||
// The type may have already been created by an import.
|
||||
Named_object* no = package->bindings()->lookup("Pointer");
|
||||
if (no == NULL)
|
||||
{
|
||||
Type* type = Type::make_pointer_type(Type::make_void_type());
|
||||
no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert(no->package() == package);
|
||||
gcc_assert(no->is_type());
|
||||
gcc_assert(no->type_value()->is_unsafe_pointer_type());
|
||||
no->type_value()->set_is_visible();
|
||||
}
|
||||
Named_type* pointer_type = no->type_value();
|
||||
if (add_to_globals)
|
||||
this->add_named_type(pointer_type);
|
||||
|
||||
Type* int_type = this->lookup_global("int")->type_value();
|
||||
|
||||
// Sizeof.
|
||||
Typed_identifier_list* results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Offsetof.
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_varargs();
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Alignof.
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", int_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, NULL, results, bloc);
|
||||
fntype->set_is_varargs();
|
||||
fntype->set_is_builtin();
|
||||
no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Typeof.
|
||||
Type* empty_interface = Type::make_interface_type(NULL, bloc);
|
||||
Typed_identifier_list* parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("i", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Typeof", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Reflect.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("it", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Reflect", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// Unreflect.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
parameters->push_back(Typed_identifier("addr", pointer_type, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", empty_interface, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("Unreflect", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// New.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("New", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
// NewArray.
|
||||
parameters = new Typed_identifier_list;
|
||||
parameters->push_back(Typed_identifier("typ", empty_interface, bloc));
|
||||
parameters->push_back(Typed_identifier("n", int_type, bloc));
|
||||
results = new Typed_identifier_list;
|
||||
results->push_back(Typed_identifier("", pointer_type, bloc));
|
||||
fntype = Type::make_function_type(NULL, parameters, results, bloc);
|
||||
no = bindings->add_function_declaration("NewArray", package, fntype, bloc);
|
||||
if (add_to_globals)
|
||||
this->add_named_object(no);
|
||||
|
||||
if (!this->imported_unsafe_)
|
||||
{
|
||||
go_imported_unsafe();
|
||||
this->imported_unsafe_ = true;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user