LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - backend.h Coverage Total Hit
Test: gcc.info Lines: 100.0 % 6 6
Test Date: 2026-02-28 14:20:25 Functions: - 0 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // backend.h -- Go frontend interface to backend  -*- C++ -*-
       2              : 
       3              : // Copyright 2011 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              : #ifndef GO_BACKEND_H
       8              : #define GO_BACKEND_H
       9              : 
      10              : #include <gmp.h>
      11              : #include <mpfr.h>
      12              : #include <mpc.h>
      13              : 
      14              : #include "operator.h"
      15              : 
      16              : // Pointers to these types are created by the backend, passed to the
      17              : // frontend, and passed back to the backend.  The types must be
      18              : // defined by the backend using these names.
      19              : 
      20              : // The backend representation of a type.
      21              : class Btype;
      22              : 
      23              : // The backend represention of an expression.
      24              : class Bexpression;
      25              : 
      26              : // The backend representation of a statement.
      27              : class Bstatement;
      28              : 
      29              : // The backend representation of a function definition or declaration.
      30              : class Bfunction;
      31              : 
      32              : // The backend representation of a block.
      33              : class Bblock;
      34              : 
      35              : // The backend representation of a variable.
      36              : class Bvariable;
      37              : 
      38              : // The backend representation of a label.
      39              : class Blabel;
      40              : 
      41              : // The backend interface.  This is a pure abstract class that a
      42              : // specific backend will implement.
      43              : 
      44         4646 : class Backend
      45              : {
      46              :  public:
      47              :   virtual ~Backend() { }
      48              : 
      49              :   // Name/type/location.  Used for function parameters, struct fields,
      50              :   // interface methods.
      51      8127607 :   struct Btyped_identifier
      52              :   {
      53              :     std::string name;
      54              :     Btype* btype;
      55              :     Location location;
      56              : 
      57      7385373 :     Btyped_identifier()
      58      7385373 :         : name(), btype(NULL), location(Linemap::unknown_location())
      59              :     { }
      60              : 
      61       217683 :     Btyped_identifier(const std::string& a_name, Btype* a_btype,
      62              :                      Location a_location)
      63       435366 :       : name(a_name), btype(a_btype), location(a_location)
      64              :     { }
      65              :   };
      66              : 
      67              :   // Types.
      68              : 
      69              :   // Produce an error type.  Actually the backend could probably just
      70              :   // crash if this is called.
      71              :   virtual Btype*
      72              :   error_type() = 0;
      73              : 
      74              :   // Get a void type.  This is used in (at least) two ways: 1) as the
      75              :   // return type of a function with no result parameters; 2)
      76              :   // unsafe.Pointer is represented as *void.
      77              :   virtual Btype*
      78              :   void_type() = 0;
      79              : 
      80              :   // Get the unnamed boolean type.
      81              :   virtual Btype*
      82              :   bool_type() = 0;
      83              : 
      84              :   // Get an unnamed integer type with the given signedness and number
      85              :   // of bits.
      86              :   virtual Btype*
      87              :   integer_type(bool is_unsigned, int bits) = 0;
      88              : 
      89              :   // Get an unnamed floating point type with the given number of bits
      90              :   // (32 or 64).
      91              :   virtual Btype*
      92              :   float_type(int bits) = 0;
      93              : 
      94              :   // Get an unnamed complex type with the given number of bits (64 or 128).
      95              :   virtual Btype*
      96              :   complex_type(int bits) = 0;
      97              : 
      98              :   // Get a pointer type.
      99              :   virtual Btype*
     100              :   pointer_type(Btype* to_type) = 0;
     101              : 
     102              :   // Get a function type.  The receiver, parameter, and results are
     103              :   // generated from the types in the Function_type.  The Function_type
     104              :   // is provided so that the names are available.  This should return
     105              :   // not the type of a Go function (which is a pointer to a struct)
     106              :   // but the type of a C function pointer (which will be used as the
     107              :   // type of the first field of the struct).  If there is more than
     108              :   // one result, RESULT_STRUCT is a struct type to hold the results,
     109              :   // and RESULTS may be ignored; if there are zero or one results,
     110              :   // RESULT_STRUCT is NULL.
     111              :   virtual Btype*
     112              :   function_type(const Btyped_identifier& receiver,
     113              :                 const std::vector<Btyped_identifier>& parameters,
     114              :                 const std::vector<Btyped_identifier>& results,
     115              :                 Btype* result_struct,
     116              :                 Location location) = 0;
     117              : 
     118              :   // Get a struct type.
     119              :   virtual Btype*
     120              :   struct_type(const std::vector<Btyped_identifier>& fields) = 0;
     121              : 
     122              :   // Get an array type.
     123              :   virtual Btype*
     124              :   array_type(Btype* element_type, Bexpression* length) = 0;
     125              : 
     126              :   // Create a placeholder pointer type.  This is used for a named
     127              :   // pointer type, since in Go a pointer type may refer to itself.
     128              :   // NAME is the name of the type, and the location is where the named
     129              :   // type is defined.  This function is also used for unnamed function
     130              :   // types with multiple results, in which case the type has no name
     131              :   // and NAME will be empty.  FOR_FUNCTION is true if this is for a C
     132              :   // pointer to function type.  A Go func type is represented as a
     133              :   // pointer to a struct, and the first field of the struct is a C
     134              :   // pointer to function.  The return value will later be passed as
     135              :   // the first parameter to set_placeholder_pointer_type or
     136              :   // set_placeholder_function_type.
     137              :   virtual Btype*
     138              :   placeholder_pointer_type(const std::string& name, Location,
     139              :                            bool for_function) = 0;
     140              : 
     141              :   // Fill in a placeholder pointer type as a pointer.  This takes a
     142              :   // type returned by placeholder_pointer_type and arranges for it to
     143              :   // point to the type that TO_TYPE points to (that is, PLACEHOLDER
     144              :   // becomes the same type as TO_TYPE).  Returns true on success,
     145              :   // false on failure.
     146              :   virtual bool
     147              :   set_placeholder_pointer_type(Btype* placeholder, Btype* to_type) = 0;
     148              : 
     149              :   // Fill in a placeholder pointer type as a function.  This takes a
     150              :   // type returned by placeholder_pointer_type and arranges for it to
     151              :   // become a real Go function type (which corresponds to a C/C++
     152              :   // pointer to function type).  FT will be something returned by the
     153              :   // function_type method.  Returns true on success, false on failure.
     154              :   virtual bool
     155              :   set_placeholder_function_type(Btype* placeholder, Btype* ft) = 0;
     156              : 
     157              :   // Create a placeholder struct type.  This is used for a named
     158              :   // struct type, as with placeholder_pointer_type.  It is also used
     159              :   // for interface types, in which case NAME will be the empty string.
     160              :   virtual Btype*
     161              :   placeholder_struct_type(const std::string& name, Location) = 0;
     162              : 
     163              :   // Fill in a placeholder struct type.  This takes a type returned by
     164              :   // placeholder_struct_type and arranges for it to become a real
     165              :   // struct type.  The parameter is as for struct_type.  Returns true
     166              :   // on success, false on failure.
     167              :   virtual bool
     168              :   set_placeholder_struct_type(Btype* placeholder,
     169              :                               const std::vector<Btyped_identifier>& fields)
     170              :                         = 0;
     171              : 
     172              :   // Create a placeholder array type.  This is used for a named array
     173              :   // type, as with placeholder_pointer_type, to handle cases like
     174              :   // type A []*A.
     175              :   virtual Btype*
     176              :   placeholder_array_type(const std::string& name, Location) = 0;
     177              : 
     178              :   // Fill in a placeholder array type.  This takes a type returned by
     179              :   // placeholder_array_type and arranges for it to become a real array
     180              :   // type.  The parameters are as for array_type.  Returns true on
     181              :   // success, false on failure.
     182              :   virtual bool
     183              :   set_placeholder_array_type(Btype* placeholder, Btype* element_type,
     184              :                              Bexpression* length) = 0;
     185              : 
     186              :   // Return a named version of a type.  The location is the location
     187              :   // of the type definition.  This will not be called for a type
     188              :   // created via placeholder_pointer_type, placeholder_struct_type, or
     189              :   // placeholder_array_type..  (It may be called for a pointer,
     190              :   // struct, or array type in a case like "type P *byte; type Q P".)
     191              :   virtual Btype*
     192              :   named_type(const std::string& name, Btype*, Location) = 0;
     193              : 
     194              :   // Create a marker for a circular pointer type.  Go pointer and
     195              :   // function types can refer to themselves in ways that are not
     196              :   // permitted in C/C++.  When a circular type is found, this function
     197              :   // is called for the circular reference.  This permits the backend
     198              :   // to decide how to handle such a type.  PLACEHOLDER is the
     199              :   // placeholder type which has already been created; if the backend
     200              :   // is prepared to handle a circular pointer type, it may simply
     201              :   // return PLACEHOLDER.  FOR_FUNCTION is true if this is for a
     202              :   // function type.
     203              :   //
     204              :   // For "type P *P" the sequence of calls will be
     205              :   //   bt1 = placeholder_pointer_type();
     206              :   //   bt2 = circular_pointer_type(bt1, false);
     207              :   //   set_placeholder_pointer_type(bt1, bt2);
     208              :   virtual Btype*
     209              :   circular_pointer_type(Btype* placeholder, bool for_function) = 0;
     210              : 
     211              :   // Return whether the argument could be a special type created by
     212              :   // circular_pointer_type.  This is used to introduce explicit type
     213              :   // conversions where needed.  If circular_pointer_type returns its
     214              :   // PLACEHOLDER parameter, this may safely always return false.
     215              :   virtual bool
     216              :   is_circular_pointer_type(Btype*) = 0;
     217              : 
     218              :   // Return the size of a type.
     219              :   virtual int64_t
     220              :   type_size(Btype*) = 0;
     221              : 
     222              :   // Return the alignment of a type.
     223              :   virtual int64_t
     224              :   type_alignment(Btype*) = 0;
     225              : 
     226              :   // Return the alignment of a struct field of this type.  This is
     227              :   // normally the same as type_alignment, but not always.
     228              :   virtual int64_t
     229              :   type_field_alignment(Btype*) = 0;
     230              : 
     231              :   // Return the offset of field INDEX in a struct type.  INDEX is the
     232              :   // entry in the FIELDS std::vector parameter of struct_type or
     233              :   // set_placeholder_struct_type.
     234              :   virtual int64_t
     235              :   type_field_offset(Btype*, size_t index) = 0;
     236              : 
     237              :   // Expressions.
     238              : 
     239              :   // Return an expression for a zero value of the given type.  This is
     240              :   // used for cases such as local variable initialization and
     241              :   // converting nil to other types.
     242              :   virtual Bexpression*
     243              :   zero_expression(Btype*) = 0;
     244              : 
     245              :   // Create an error expression. This is used for cases which should
     246              :   // not occur in a correct program, in order to keep the compilation
     247              :   // going without crashing.
     248              :   virtual Bexpression*
     249              :   error_expression() = 0;
     250              : 
     251              :   // Create a nil pointer expression.
     252              :   virtual Bexpression*
     253              :   nil_pointer_expression() = 0;
     254              : 
     255              :   // Create a reference to a variable.
     256              :   virtual Bexpression*
     257              :   var_expression(Bvariable* var, Location) = 0;
     258              : 
     259              :   // Create an expression that indirects through the pointer expression EXPR
     260              :   // (i.e., return the expression for *EXPR). KNOWN_VALID is true if the pointer
     261              :   // is known to point to a valid memory location.  BTYPE is the expected type
     262              :   // of the indirected EXPR.
     263              :   virtual Bexpression*
     264              :   indirect_expression(Btype* btype, Bexpression* expr, bool known_valid,
     265              :                       Location) = 0;
     266              : 
     267              :   // Return an expression that declares a constant named NAME with the
     268              :   // constant value VAL in BTYPE.
     269              :   virtual Bexpression*
     270              :   named_constant_expression(Btype* btype, const std::string& name,
     271              :                              Bexpression* val, Location) = 0;
     272              : 
     273              :   // Return an expression for the multi-precision integer VAL in BTYPE.
     274              :   virtual Bexpression*
     275              :   integer_constant_expression(Btype* btype, mpz_t val) = 0;
     276              : 
     277              :   // Return an expression for the floating point value VAL in BTYPE.
     278              :   virtual Bexpression*
     279              :   float_constant_expression(Btype* btype, mpfr_t val) = 0;
     280              : 
     281              :   // Return an expression for the complex value VAL in BTYPE.
     282              :   virtual Bexpression*
     283              :   complex_constant_expression(Btype* btype, mpc_t val) = 0;
     284              : 
     285              :   // Return an expression for the string value VAL.
     286              :   virtual Bexpression*
     287              :   string_constant_expression(const std::string& val) = 0;
     288              : 
     289              :   // Return an expression for the boolean value VAL.
     290              :   virtual Bexpression*
     291              :   boolean_constant_expression(bool val) = 0;
     292              : 
     293              :   // Return an expression for the real part of BCOMPLEX.
     294              :   virtual Bexpression*
     295              :   real_part_expression(Bexpression* bcomplex, Location) = 0;
     296              : 
     297              :   // Return an expression for the imaginary part of BCOMPLEX.
     298              :   virtual Bexpression*
     299              :   imag_part_expression(Bexpression* bcomplex, Location) = 0;
     300              : 
     301              :   // Return an expression for the complex number (BREAL, BIMAG).
     302              :   virtual Bexpression*
     303              :   complex_expression(Bexpression* breal, Bexpression* bimag, Location) = 0;
     304              : 
     305              :   // Return an expression that converts EXPR to TYPE.
     306              :   virtual Bexpression*
     307              :   convert_expression(Btype* type, Bexpression* expr, Location) = 0;
     308              : 
     309              :   // Create an expression for the address of a function.  This is used to
     310              :   // get the address of the code for a function.
     311              :   virtual Bexpression*
     312              :   function_code_expression(Bfunction*, Location) = 0;
     313              : 
     314              :   // Create an expression that takes the address of an expression.
     315              :   virtual Bexpression*
     316              :   address_expression(Bexpression*, Location) = 0;
     317              : 
     318              :   // Return an expression for the field at INDEX in BSTRUCT.
     319              :   virtual Bexpression*
     320              :   struct_field_expression(Bexpression* bstruct, size_t index, Location) = 0;
     321              : 
     322              :   // Create an expression that executes BSTAT before BEXPR.
     323              :   virtual Bexpression*
     324              :   compound_expression(Bstatement* bstat, Bexpression* bexpr, Location) = 0;
     325              : 
     326              :   // Return an expression that executes THEN_EXPR if CONDITION is true, or
     327              :   // ELSE_EXPR otherwise and returns the result as type BTYPE, within the
     328              :   // specified function FUNCTION.  ELSE_EXPR may be NULL.  BTYPE may be NULL.
     329              :   virtual Bexpression*
     330              :   conditional_expression(Bfunction* function, Btype* btype,
     331              :                          Bexpression* condition, Bexpression* then_expr,
     332              :                          Bexpression* else_expr, Location) = 0;
     333              : 
     334              :   // Return an expression for the unary operation OP EXPR.
     335              :   // Supported values of OP are (from operators.h):
     336              :   //    MINUS, NOT, XOR.
     337              :   virtual Bexpression*
     338              :   unary_expression(Operator op, Bexpression* expr, Location) = 0;
     339              : 
     340              :   // Return an expression for the binary operation LEFT OP RIGHT.
     341              :   // Supported values of OP are (from operators.h):
     342              :   //    EQEQ, NOTEQ, LT, LE, GT, GE, PLUS, MINUS, OR, XOR, MULT, DIV, MOD,
     343              :   //    LSHIFT, RSHIFT, AND, NOT.
     344              :   virtual Bexpression*
     345              :   binary_expression(Operator op, Bexpression* left, Bexpression* right,
     346              :                     Location) = 0;
     347              : 
     348              :   // Return an expression that constructs BTYPE with VALS.  BTYPE must be the
     349              :   // backend representation a of struct.  VALS must be in the same order as the
     350              :   // corresponding fields in BTYPE.
     351              :   virtual Bexpression*
     352              :   constructor_expression(Btype* btype, const std::vector<Bexpression*>& vals,
     353              :                          Location) = 0;
     354              : 
     355              :   // Return an expression that constructs an array of BTYPE with INDEXES and
     356              :   // VALS.  INDEXES and VALS must have the same amount of elements. Each index
     357              :   // in INDEXES must be in the same order as the corresponding value in VALS.
     358              :   virtual Bexpression*
     359              :   array_constructor_expression(Btype* btype,
     360              :                                const std::vector<unsigned long>& indexes,
     361              :                                const std::vector<Bexpression*>& vals,
     362              :                                Location) = 0;
     363              : 
     364              :   // Return an expression for the address of BASE[INDEX].
     365              :   // BASE has a pointer type.  This is used for slice indexing.
     366              :   virtual Bexpression*
     367              :   pointer_offset_expression(Bexpression* base, Bexpression* index,
     368              :                             Location) = 0;
     369              : 
     370              :   // Return an expression for ARRAY[INDEX] as an l-value.  ARRAY is a valid
     371              :   // fixed-length array, not a slice.
     372              :   virtual Bexpression*
     373              :   array_index_expression(Bexpression* array, Bexpression* index, Location) = 0;
     374              : 
     375              :   // Create an expression for a call to FN with ARGS, taking place within
     376              :   // caller CALLER.
     377              :   virtual Bexpression*
     378              :   call_expression(Bfunction *caller, Bexpression* fn,
     379              :                   const std::vector<Bexpression*>& args,
     380              :                   Bexpression* static_chain, Location) = 0;
     381              : 
     382              :   // Statements.
     383              : 
     384              :   // Create an error statement.  This is used for cases which should
     385              :   // not occur in a correct program, in order to keep the compilation
     386              :   // going without crashing.
     387              :   virtual Bstatement*
     388              :   error_statement() = 0;
     389              : 
     390              :   // Create an expression statement within the specified function.
     391              :   virtual Bstatement*
     392              :   expression_statement(Bfunction*, Bexpression*) = 0;
     393              : 
     394              :   // Create a variable initialization statement in the specified
     395              :   // function.  This initializes a local variable at the point in the
     396              :   // program flow where it is declared.
     397              :   virtual Bstatement*
     398              :   init_statement(Bfunction*, Bvariable* var, Bexpression* init) = 0;
     399              : 
     400              :   // Create an assignment statement within the specified function.
     401              :   virtual Bstatement*
     402              :   assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
     403              :                        Location) = 0;
     404              : 
     405              :   // Create a return statement, passing the representation of the
     406              :   // function and the list of values to return.
     407              :   virtual Bstatement*
     408              :   return_statement(Bfunction*, const std::vector<Bexpression*>&,
     409              :                    Location) = 0;
     410              : 
     411              :   // Create an if statement within a function.  ELSE_BLOCK may be NULL.
     412              :   virtual Bstatement*
     413              :   if_statement(Bfunction*, Bexpression* condition,
     414              :                Bblock* then_block, Bblock* else_block,
     415              :                Location) = 0;
     416              : 
     417              :   // Create a switch statement where the case values are constants.
     418              :   // CASES and STATEMENTS must have the same number of entries.  If
     419              :   // VALUE matches any of the list in CASES[i], which will all be
     420              :   // integers, then STATEMENTS[i] is executed.  STATEMENTS[i] will
     421              :   // either end with a goto statement or will fall through into
     422              :   // STATEMENTS[i + 1].  CASES[i] is empty for the default clause,
     423              :   // which need not be last.  FUNCTION is the current function.
     424              :   virtual Bstatement*
     425              :   switch_statement(Bfunction* function, Bexpression* value,
     426              :                    const std::vector<std::vector<Bexpression*> >& cases,
     427              :                    const std::vector<Bstatement*>& statements,
     428              :                    Location) = 0;
     429              : 
     430              :   // Create a single statement from two statements.
     431              :   virtual Bstatement*
     432              :   compound_statement(Bstatement*, Bstatement*) = 0;
     433              : 
     434              :   // Create a single statement from a list of statements.
     435              :   virtual Bstatement*
     436              :   statement_list(const std::vector<Bstatement*>&) = 0;
     437              : 
     438              :   // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if
     439              :   // an exception occurs. EXCEPT_STMT may be NULL.  FINALLY_STMT may be NULL and
     440              :   // if not NULL, it will always be executed.  This is used for handling defers
     441              :   // in Go functions.  In C++, the resulting code is of this form:
     442              :   //   try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
     443              :   virtual Bstatement*
     444              :   exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt,
     445              :                               Bstatement* finally_stmt, Location) = 0;
     446              : 
     447              :   // Blocks.
     448              : 
     449              :   // Create a block.  The frontend will call this function when it
     450              :   // starts converting a block within a function.  FUNCTION is the
     451              :   // current function.  ENCLOSING is the enclosing block; it will be
     452              :   // NULL for the top-level block in a function.  VARS is the list of
     453              :   // local variables defined within this block; each entry will be
     454              :   // created by the local_variable function.  START_LOCATION is the
     455              :   // location of the start of the block, more or less the location of
     456              :   // the initial curly brace.  END_LOCATION is the location of the end
     457              :   // of the block, more or less the location of the final curly brace.
     458              :   // The statements will be added after the block is created.
     459              :   virtual Bblock*
     460              :   block(Bfunction* function, Bblock* enclosing,
     461              :         const std::vector<Bvariable*>& vars,
     462              :         Location start_location, Location end_location) = 0;
     463              : 
     464              :   // Add the statements to a block.  The block is created first.  Then
     465              :   // the statements are created.  Then the statements are added to the
     466              :   // block.  This will called exactly once per block.  The vector may
     467              :   // be empty if there are no statements.
     468              :   virtual void
     469              :   block_add_statements(Bblock*, const std::vector<Bstatement*>&) = 0;
     470              : 
     471              :   // Return the block as a statement.  This is used to include a block
     472              :   // in a list of statements.
     473              :   virtual Bstatement*
     474              :   block_statement(Bblock*) = 0;
     475              : 
     476              :   // Variables.
     477              : 
     478              :   // Create an error variable.  This is used for cases which should
     479              :   // not occur in a correct program, in order to keep the compilation
     480              :   // going without crashing.
     481              :   virtual Bvariable*
     482              :   error_variable() = 0;
     483              : 
     484              :   // Bit flags to pass to the various methods that return Bvariable*.
     485              :   // Not all flags are meaningful for all methods.
     486              : 
     487              :   // Set if the variable's address is taken.  For a local variable
     488              :   // this implies that the address does not escape the function, as
     489              :   // otherwise the variable would be on the heap.
     490              :   static const unsigned int variable_address_is_taken = 1 << 0;
     491              : 
     492              :   // Set if the variable is defined in some other package.  Only
     493              :   // meaningful for the global_variable method.  At most one of
     494              :   // is_external, is_hidden, and is_common may be set.
     495              :   static const unsigned int variable_is_external = 1 << 1;
     496              : 
     497              :   // Set if the variable is not exported, and as such is only defined
     498              :   // in the current package.  Only meaningful for global_variable,
     499              :   // implicit_variable, and immutable_struct.  At most one of
     500              :   // is_external, is_hidden, and is_common may be set.
     501              :   static const unsigned variable_is_hidden = 1 << 2;
     502              : 
     503              :   // Set if the variable should be treated as a common variable:
     504              :   // multiple definitions with different sizes permitted in different
     505              :   // object files, all merged into the largest definition at link
     506              :   // time.  Only meaningful for implicit_variable and immutable_struct.
     507              :   // At most one of is_external, is_hidden, and is_common may be set.
     508              :   static const unsigned int variable_is_common = 1 << 3;
     509              : 
     510              :   // Set if the variable should be put into a unique section if
     511              :   // possible; this is intended to permit the linker to garbage
     512              :   // collect the value if it is not referenced.  Only meaningful for
     513              :   // global_variable.
     514              :   static const unsigned int variable_in_unique_section = 1 << 4;
     515              : 
     516              :   // Set if the variable should be treated as immutable.  Only
     517              :   // meaningful for implicit_variable.  For example, this is set for
     518              :   // slice initializers if the values must be copied to the heap.
     519              :   static const unsigned int variable_is_constant = 1 << 5;
     520              : 
     521              :   // Create a global variable. NAME is the package-qualified name of
     522              :   // the variable.  ASM_NAME is the encoded identifier for the
     523              :   // variable, incorporating the package, and made safe for the
     524              :   // assembler.  BTYPE is the type of the variable.  FLAGS is the bit
     525              :   // flags defined above.  LOCATION is where the variable was defined.
     526              :   virtual Bvariable*
     527              :   global_variable(const std::string& name, const std::string& asm_name,
     528              :                   Btype* btype, unsigned int flags, Location location) = 0;
     529              : 
     530              :   // A global variable will 1) be initialized to zero, or 2) be
     531              :   // initialized to a constant value, or 3) be initialized in the init
     532              :   // function.  In case 2, the frontend will call
     533              :   // global_variable_set_init to set the initial value.  If this is
     534              :   // not called, the backend should initialize a global variable to 0.
     535              :   // The init function may then assign a value to it.
     536              :   virtual void
     537              :   global_variable_set_init(Bvariable*, Bexpression*) = 0;
     538              : 
     539              :   // Create a local variable.  The frontend will create the local
     540              :   // variables first, and then create the block which contains them.
     541              :   // FUNCTION is the function in which the variable is defined.  NAME
     542              :   // is the name of the variable.  TYPE is the type.  DECL_VAR, if not
     543              :   // null, gives the location at which the value of this variable may
     544              :   // be found, typically used to create an inner-scope reference to an
     545              :   // outer-scope variable, to extend the lifetime of the variable beyond
     546              :   // the inner scope.  FLAGS is the bit flags defined above.
     547              :   // LOCATION is where the variable is defined.  For each local variable
     548              :   // the frontend will call init_statement to set the initial value.
     549              :   virtual Bvariable*
     550              :   local_variable(Bfunction* function, const std::string& name, Btype* type,
     551              :                  Bvariable* decl_var, unsigned int flags,
     552              :                  Location location) = 0;
     553              : 
     554              :   // Create a function parameter.  This is an incoming parameter, not
     555              :   // a result parameter (result parameters are treated as local
     556              :   // variables).  The arguments are as for local_variable.
     557              :   virtual Bvariable*
     558              :   parameter_variable(Bfunction* function, const std::string& name,
     559              :                      Btype* type, unsigned int flags, Location location) = 0;
     560              : 
     561              :   // Create a static chain parameter.  This is the closure parameter.
     562              :   virtual Bvariable*
     563              :   static_chain_variable(Bfunction* function, const std::string& name,
     564              :                         Btype* type, unsigned int flags,
     565              :                         Location location) = 0;
     566              : 
     567              :   // Create a temporary variable.  A temporary variable has no name,
     568              :   // just a type.  We pass in FUNCTION and BLOCK in case they are
     569              :   // needed.  If INIT is not NULL, the variable should be initialized
     570              :   // to that value.  Otherwise the initial value is irrelevant--the
     571              :   // backend does not have to explicitly initialize it to zero.
     572              :   // FLAGS is the bit flags defined above.  LOCATION is the location of
     573              :   // the statement or expression which requires creating the temporary
     574              :   // variable, and may not be very useful.  This function should
     575              :   // return a variable which can be referenced later and should set
     576              :   // *PSTATEMENT to a statement which initializes the variable.
     577              :   virtual Bvariable*
     578              :   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
     579              :                      unsigned int flags, Location location,
     580              :                      Bstatement** pstatement) = 0;
     581              : 
     582              :   // Create an implicit variable that is compiler-defined.  This is
     583              :   // used when generating GC data and roots, when storing the values
     584              :   // of a slice constructor, and for the zero value of types.  This returns a
     585              :   // Bvariable because it corresponds to an initialized variable in C.
     586              :   //
     587              :   // NAME is the name to use for the initialized variable this will create.
     588              :   //
     589              :   // ASM_NAME is encoded assembler-friendly version of the name, or the
     590              :   // empty string if no encoding is needed.
     591              :   //
     592              :   // TYPE is the type of the implicit variable.
     593              :   //
     594              :   // FLAGS is the bit flags defined above.
     595              :   //
     596              :   // If ALIGNMENT is not zero, it is the desired alignment of the variable.
     597              :   virtual Bvariable*
     598              :   implicit_variable(const std::string& name, const std::string& asm_name,
     599              :                     Btype* type, unsigned int flags, int64_t alignment) = 0;
     600              : 
     601              : 
     602              :   // Set the initial value of a variable created by implicit_variable.
     603              :   // This must be called even if there is no initializer, i.e., INIT is NULL.
     604              :   // The NAME, TYPE, and FLAGS parameters are the same ones passed to
     605              :   // implicit_variable.  INIT will be a composite literal of type
     606              :   // TYPE.  It will not contain any function calls or anything else
     607              :   // that can not be put into a read-only data section.  It may
     608              :   // contain the address of variables created by implicit_variable.
     609              :   //
     610              :   // If variable_is_common is set in FLAGS, INIT will be NULL, and the
     611              :   // variable should be initialized to all zeros.
     612              :   virtual void
     613              :   implicit_variable_set_init(Bvariable*, const std::string& name, Btype* type,
     614              :                              unsigned int flags, Bexpression* init) = 0;
     615              : 
     616              :   // Create a reference to a named implicit variable defined in some
     617              :   // other package.  This will be a variable created by a call to
     618              :   // implicit_variable with the same NAME, ASM_NAME and TYPE and with
     619              :   // variable_is_common not set in FLAGS.  This corresponds to an
     620              :   // extern global variable in C.
     621              :   virtual Bvariable*
     622              :   implicit_variable_reference(const std::string& name,
     623              :                               const std::string& asm_name,
     624              :                               Btype* type) = 0;
     625              : 
     626              :   // Create a named immutable initialized data structure.  This is
     627              :   // used for type descriptors, map descriptors, and function
     628              :   // descriptors.  This returns a Bvariable because it corresponds to
     629              :   // an initialized const variable in C.
     630              :   //
     631              :   // NAME is the name to use for the initialized global variable which
     632              :   // this call will create.
     633              :   //
     634              :   // ASM_NAME is the encoded, assembler-friendly version of NAME, or
     635              :   // the empty string if no encoding is needed.
     636              :   //
     637              :   // FLAGS is the bit flags defined above.  The variable_is_common
     638              :   // flag will be set if NAME may be defined by several packages, and
     639              :   // the linker should merge all such definitions.  If the
     640              :   // variable_is_common flag is not set, NAME should be defined in
     641              :   // only one file.  In general variable_is_common will be set for the
     642              :   // type descriptor of an unnamed type or a builtin type.
     643              :   //
     644              :   // TYPE will be a struct type; the type of the returned expression
     645              :   // must be a pointer to this struct type.
     646              :   //
     647              :   // We must create the named structure before we know its
     648              :   // initializer, because the initializer may refer to its own
     649              :   // address.  After calling this the frontend will call
     650              :   // immutable_struct_set_init.
     651              :   virtual Bvariable*
     652              :   immutable_struct(const std::string& name, const std::string& asm_name,
     653              :                    unsigned int flags, Btype* type, Location) = 0;
     654              : 
     655              :   // Set the initial value of a variable created by immutable_struct.
     656              :   // The NAME, FLAGS, TYPE, and location parameters are the same ones
     657              :   // passed to immutable_struct.  INITIALIZER will be a composite
     658              :   // literal of type TYPE.  It will not contain any function calls or
     659              :   // anything else that can not be put into a read-only data section.
     660              :   // It may contain the address of variables created by
     661              :   // immutable_struct.
     662              :   virtual void
     663              :   immutable_struct_set_init(Bvariable*, const std::string& name,
     664              :                             unsigned int flags, Btype* type,
     665              :                             Location, Bexpression* initializer) = 0;
     666              : 
     667              :   // Create a reference to a named immutable initialized data
     668              :   // structure defined in some other package.  This will be a
     669              :   // structure created by a call to immutable_struct with the same
     670              :   // NAME, ASM_NAME and TYPE and with variable_is_common not set in
     671              :   // flags.  This corresponds to an extern const global variable in C.
     672              :   virtual Bvariable*
     673              :   immutable_struct_reference(const std::string& name,
     674              :                              const std::string& asm_name,
     675              :                              Btype* type, Location) = 0;
     676              : 
     677              :   // Labels.
     678              : 
     679              :   // Create a new label.  NAME will be empty if this is a label
     680              :   // created by the frontend for a loop construct.  The location is
     681              :   // where the label is defined.
     682              :   virtual Blabel*
     683              :   label(Bfunction*, const std::string& name, Location) = 0;
     684              : 
     685              :   // Create a statement which defines a label.  This statement will be
     686              :   // put into the codestream at the point where the label should be
     687              :   // defined.
     688              :   virtual Bstatement*
     689              :   label_definition_statement(Blabel*) = 0;
     690              : 
     691              :   // Create a goto statement to a label.
     692              :   virtual Bstatement*
     693              :   goto_statement(Blabel*, Location) = 0;
     694              : 
     695              :   // Create an expression for the address of a label.  This is used to
     696              :   // get the return address of a deferred function which may call
     697              :   // recover.
     698              :   virtual Bexpression*
     699              :   label_address(Blabel*, Location) = 0;
     700              : 
     701              :   // Functions.
     702              : 
     703              :   // Create an error function.  This is used for cases which should
     704              :   // not occur in a correct program, in order to keep the compilation
     705              :   // going without crashing.
     706              :   virtual Bfunction*
     707              :   error_function() = 0;
     708              : 
     709              :   // Bit flags to pass to the function method.
     710              : 
     711              :   // Set if the function should be visible outside of the current
     712              :   // compilation unit.
     713              :   static const unsigned int function_is_visible = 1 << 0;
     714              : 
     715              :   // Set if this is a function declaration rather than a definition;
     716              :   // the definition will be in another compilation unit.
     717              :   static const unsigned int function_is_declaration = 1 << 1;
     718              : 
     719              :   // Set if the function can be inlined.  This is normally set, but is
     720              :   // false for functions that may not be inlined because they call
     721              :   // recover and must be visible for correct panic recovery.
     722              :   static const unsigned int function_is_inlinable = 1 << 2;
     723              : 
     724              :   // Set if the function may not split the stack.  This is set for the
     725              :   // implementation of recover itself, among other things.
     726              :   static const unsigned int function_no_split_stack = 1 << 3;
     727              : 
     728              :   // Set if the function does not return.  This is set for the
     729              :   // implementation of panic.
     730              :   static const unsigned int function_does_not_return = 1 << 4;
     731              : 
     732              :   // Set if the function should be put in a unique section if
     733              :   // possible.  This is used for field tracking.
     734              :   static const unsigned int function_in_unique_section = 1 << 5;
     735              : 
     736              :   // Set if the function should be available for inlining in the
     737              :   // backend, but should not be emitted as a standalone function.  Any
     738              :   // call to the function that is not inlined should be treated as a
     739              :   // call to a function defined in a different compilation unit.  This
     740              :   // is like a C99 function marked inline but not extern.
     741              :   static const unsigned int function_only_inline = 1 << 6;
     742              : 
     743              :   // Declare or define a function of FNTYPE.
     744              :   // NAME is the Go name of the function.  ASM_NAME, if not the empty
     745              :   // string, is the name that should be used in the symbol table; this
     746              :   // will be non-empty if a magic extern comment is used.  FLAGS is
     747              :   // bit flags described above.
     748              :   virtual Bfunction*
     749              :   function(Btype* fntype, const std::string& name, const std::string& asm_name,
     750              :            unsigned int flags, Location) = 0;
     751              : 
     752              :   // Create a statement that runs all deferred calls for FUNCTION.  This should
     753              :   // be a statement that looks like this in C++:
     754              :   //   finish:
     755              :   //     try { DEFER_RETURN; } catch { CHECK_DEFER; goto finish; }
     756              :   virtual Bstatement*
     757              :   function_defer_statement(Bfunction* function, Bexpression* undefer,
     758              :                            Bexpression* check_defer, Location) = 0;
     759              : 
     760              :   // Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
     761              :   // This will only be called for a function definition.  Returns true on
     762              :   // success, false on failure.
     763              :   virtual bool
     764              :   function_set_parameters(Bfunction* function,
     765              :                          const std::vector<Bvariable*>& param_vars) = 0;
     766              : 
     767              :   // Set the function body for FUNCTION using the code in CODE_STMT.  Returns
     768              :   // true on success, false on failure.
     769              :   virtual bool
     770              :   function_set_body(Bfunction* function, Bstatement* code_stmt) = 0;
     771              : 
     772              :   // Look up a named built-in function in the current backend implementation.
     773              :   // Returns NULL if no built-in function by that name exists.
     774              :   virtual Bfunction*
     775              :   lookup_builtin(const std::string&) = 0;
     776              : 
     777              :   // Utility.
     778              : 
     779              :   // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
     780              :   // FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
     781              :   virtual void
     782              :   write_global_definitions(const std::vector<Btype*>& type_decls,
     783              :                            const std::vector<Bexpression*>& constant_decls,
     784              :                            const std::vector<Bfunction*>& function_decls,
     785              :                            const std::vector<Bvariable*>& variable_decls) = 0;
     786              : 
     787              :   // Write SIZE bytes of export data from BYTES to the proper
     788              :   // section in the output object file.
     789              :   virtual void
     790              :   write_export_data(const char* bytes, unsigned int size) = 0;
     791              : };
     792              : 
     793              : #endif // !defined(GO_BACKEND_H)
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.