class Function_type;
class Expression;
class Statement;
+class Temporary_statement;
class Block;
class Function;
class Bindings;
class Named_object;
class Label;
class Translate_context;
+class Backend;
class Export;
class Import;
+class Bexpression;
+class Bstatement;
+class Bblock;
+class Bvariable;
+class Blabel;
// This file declares the basic classes used to hold the internal
// representation of Go which is built by the parser.
public:
// Create the IR, passing in the sizes of the types "int" and
// "uintptr" in bits.
- Gogo(int int_type_size, int pointer_size);
+ Gogo(Backend* backend, int int_type_size, int pointer_size);
+
+ // Get the backend generator.
+ Backend*
+ backend()
+ { return this->backend_; }
// Get the package name.
const std::string&
tree
go_string_constant_tree(const std::string&);
- // Send a value on a channel.
- static tree
- send_on_channel(tree channel, tree val, bool blocking, bool for_select,
- source_location);
-
// Receive a value from a channel.
static tree
receive_from_channel(tree type_tree, tree channel, bool for_select,
typedef Unordered_map_hash(const Type*, tree, Type_hash_identical,
Type_identical) Type_descriptor_decls;
+ // The backend generator.
+ Backend* backend_;
// The package we are compiling.
Package* package_;
// The list of currently open functions during parsing.
bool
may_fall_through() const;
- // Return a tree of the code in this block.
- tree
- get_tree(Translate_context*);
+ // Convert the block to the backend representation.
+ Bblock*
+ get_backend(Translate_context*);
// Iterate over statements.
this->enclosing_ = enclosing;
}
- // Create the named result variables in the outer block.
+ // The result variables.
+ typedef std::vector<Named_object*> Results;
+
+ // Create the result variables in the outer block.
void
- create_named_result_variables(Gogo*);
+ create_result_variables(Gogo*);
// Update the named result variables when cloning a function which
// calls recover.
void
- update_named_result_variables();
+ update_result_variables();
+
+ // Return the result variables.
+ Results*
+ result_variables()
+ { return this->results_; }
+
+ // Whether the result variables have names.
+ bool
+ results_are_named() const
+ { return this->results_are_named_; }
// Add a new field to the closure variable.
void
return_value(Gogo*, Named_object*, source_location, tree* stmt_list) const;
// Get a tree for the variable holding the defer stack.
- tree
+ Expression*
defer_stack(source_location);
// Export the function.
void
build_defer_wrapper(Gogo*, Named_object*, tree*, tree*);
- typedef std::vector<Named_object*> Named_results;
-
typedef std::vector<std::pair<Named_object*,
source_location> > Closure_fields;
// The enclosing function. This is NULL when there isn't one, which
// is the normal case.
Function* enclosing_;
- // The named result variables, if any.
- Named_results* named_results_;
+ // The result variables, if any.
+ Results* results_;
// If there is a closure, this is the list of variables which appear
// in the closure. This is created by the parser, and then resolved
// to a real type when we lower parse trees.
Labels labels_;
// The function decl.
tree fndecl_;
- // A variable holding the defer stack variable. This is NULL unless
- // we actually need a defer stack.
- tree defer_stack_;
+ // The defer stack variable. A pointer to this variable is used to
+ // distinguish the defer stack for one function from another. This
+ // is NULL unless we actually need a defer stack.
+ Temporary_statement* defer_stack_;
+ // True if the result variables are named.
+ bool results_are_named_;
// True if this function calls the predeclared recover function.
bool calls_recover_;
// True if this a thunk built for a function which calls recover.
set_address_taken()
{ this->is_address_taken_ = true; }
+ // Get the backend representation of the variable.
+ Bvariable*
+ get_backend_variable(Gogo*, Named_object*, const Package*,
+ const std::string&);
+
// Get the initial value of the variable as a tree. This may only
// be called if has_pre_init() returns false.
tree
Block* preinit_;
// Location of variable definition.
source_location location_;
+ // Backend representation.
+ Bvariable* backend_;
// Whether this is a global variable.
bool is_global_ : 1;
// Whether this is a function parameter.
class Result_variable
{
public:
- Result_variable(Type* type, Function* function, int index)
- : type_(type), function_(function), index_(index),
- is_address_taken_(false)
+ Result_variable(Type* type, Function* function, int index,
+ source_location location)
+ : type_(type), function_(function), index_(index), location_(location),
+ backend_(NULL), is_address_taken_(false)
{ }
// Get the type of the result variable.
index() const
{ return this->index_; }
+ // The location of the variable definition.
+ source_location
+ location() const
+ { return this->location_; }
+
// Whether this variable's address is taken.
bool
is_address_taken() const
set_function(Function* function)
{ this->function_ = function; }
+ // Get the backend representation of the variable.
+ Bvariable*
+ get_backend_variable(Gogo*, Named_object*, const std::string&);
+
private:
// Type of result variable.
Type* type_;
Function* function_;
// Index in list of results.
int index_;
+ // Where the result variable is defined.
+ source_location location_;
+ // Backend representation.
+ Bvariable* backend_;
// Whether something takes the address of this variable.
bool is_address_taken_;
};
source_location
location() const;
+ // Convert a variable to the backend representation.
+ Bvariable*
+ get_backend_variable(Gogo*, Named_object* function);
+
// Return a tree for the external identifier for this object.
tree
get_id(Gogo*);
{
public:
Label(const std::string& name)
- : name_(name), location_(0), is_used_(false), decl_(NULL)
+ : name_(name), location_(0), is_used_(false), blabel_(NULL)
{ }
// Return the label's name.
this->location_ = location;
}
- // Return the LABEL_DECL for this decl.
- tree
- get_decl();
+ // Return the backend representation for this label.
+ Blabel*
+ get_backend_label(Translate_context*);
- // Return an expression for the address of this label.
- tree
- get_addr(source_location location);
+ // Return an expression for the address of this label. This is used
+ // to get the return address of a deferred function to see whether
+ // the function may call recover.
+ Bexpression*
+ get_addr(Translate_context*, source_location location);
private:
// The name of the label.
source_location location_;
// Whether the label has been used.
bool is_used_;
- // The LABEL_DECL.
- tree decl_;
+ // The backend representation.
+ Blabel* blabel_;
};
// An unnamed label. These are used when lowering loops.
{
public:
Unnamed_label(source_location location)
- : location_(location), decl_(NULL)
+ : location_(location), blabel_(NULL)
{ }
// Get the location where the label is defined.
{ this->location_ = location; }
// Return a statement which defines this label.
- tree
- get_definition();
+ Bstatement*
+ get_definition(Translate_context*);
// Return a goto to this label from LOCATION.
- tree
- get_goto(source_location location);
+ Bstatement*
+ get_goto(Translate_context*, source_location location);
private:
- // Return the LABEL_DECL to use with GOTO_EXPR.
- tree
- get_decl();
+ // Return the backend representation.
+ Blabel*
+ get_blabel(Translate_context*);
// The location where the label is defined.
source_location location_;
- // The LABEL_DECL.
- tree decl_;
+ // The backend representation of this label.
+ Blabel* blabel_;
};
// An imported package.
Expressions_seen* expressions_seen_;
};
-// When translating the gogo IR into trees, this is the context we
-// pass down the blocks and statements.
+// When translating the gogo IR into the backend data structure, this
+// is the context we pass down the blocks and statements.
class Translate_context
{
public:
Translate_context(Gogo* gogo, Named_object* function, Block* block,
- tree block_tree)
- : gogo_(gogo), function_(function), block_(block), block_tree_(block_tree),
- is_const_(false)
+ Bblock* bblock)
+ : gogo_(gogo), backend_(gogo->backend()), function_(function),
+ block_(block), bblock_(bblock), is_const_(false)
{ }
// Accessors.
gogo()
{ return this->gogo_; }
+ Backend*
+ backend()
+ { return this->backend_; }
+
Named_object*
function()
{ return this->function_; }
block()
{ return this->block_; }
- tree
- block_tree()
- { return this->block_tree_; }
+ Bblock*
+ bblock()
+ { return this->bblock_; }
bool
is_const()
private:
// The IR for the entire compilation unit.
Gogo* gogo_;
- // The function we are currently translating.
+ // The generator for the backend data structures.
+ Backend* backend_;
+ // The function we are currently translating. NULL if not in a
+ // function, e.g., the initializer of a global variable.
Named_object* function_;
- // The block we are currently translating.
+ // The block we are currently translating. NULL if not in a
+ // function.
Block *block_;
- // The BLOCK node for the current block.
- tree block_tree_;
+ // The backend representation of the current block. NULL if block_
+ // is NULL.
+ Bblock* bblock_;
// Whether this is being evaluated in a constant context. This is
// used for type descriptor initializers.
bool is_const_;