check_make_expression(Expression_list* args, source_location location)
{ return this->do_check_make_expression(args, location); }
+ // Convert the builtin named types.
+ static void
+ convert_builtin_named_types(Gogo*);
+
// Return a tree representing this type.
tree
get_tree(Gogo*);
static Type_trees type_trees;
+ // A list of builtin named types.
+ static std::vector<Named_type*> named_builtin_types;
+
// The type classification.
Type_classification classification_;
// The tree representation of the type, once it has been determined.
Function_type*
copy_with_receiver(Type*) const;
+ static Type*
+ make_function_type_descriptor_type();
+
protected:
int
do_traverse(Traverse*);
do_export(Export*) const;
private:
- static Type*
- make_function_type_descriptor_type();
-
Expression*
type_descriptor_params(Type*, const Typed_identifier*,
const Typed_identifier_list*);
static Pointer_type*
do_import(Import*);
+ static Type*
+ make_pointer_type_descriptor_type();
+
protected:
int
do_traverse(Traverse*);
do_export(Export*) const;
private:
- static Type*
- make_pointer_type_descriptor_type();
-
// The type to which this type points.
Type* to_type_;
};
public:
Struct_type(Struct_field_list* fields, source_location location)
: Type(TYPE_STRUCT),
- fields_(fields), location_(location), all_methods_(NULL),
- prerequisites_()
+ fields_(fields), location_(location), all_methods_(NULL)
{ }
// Return the field NAME. This only looks at local fields, not at
tree
fill_in_tree(Gogo*, tree);
- // Note that a struct must be converted to the backend
- // representation before we convert this struct.
- void
- add_prerequisite(Named_type* nt)
- { this->prerequisites_.push_back(nt); }
-
- // If there are any structs which must be converted to the backend
- // representation before this one, convert them.
- void
- convert_prerequisites(Gogo*);
+ static Type*
+ make_struct_type_descriptor_type();
protected:
int
do_export(Export*) const;
private:
+ // Used to avoid infinite loops in field_reference_depth.
+ struct Saw_named_type
+ {
+ Saw_named_type* next;
+ Named_type* nt;
+ };
+
Field_reference_expression*
field_reference_depth(Expression* struct_expr, const std::string& name,
- source_location, unsigned int* depth) const;
-
- static Type*
- make_struct_type_descriptor_type();
+ source_location, Saw_named_type*,
+ unsigned int* depth) const;
// The fields of the struct.
Struct_field_list* fields_;
source_location location_;
// If this struct is unnamed, a list of methods.
Methods* all_methods_;
- // A list of structs which must be converted to the backend
- // representation before this struct can be converted. This is for
- // cases like
- // type S1 { p *S2 }
- // type S2 { s S1 }
- // where we must start converting S2 before we start converting S1.
- // That is because we can fully convert S1 before S2 is complete,
- // but we can not fully convert S2 before S1 is complete. If we
- // start converting S1 first, we won't be able to convert S2.
- std::vector<Named_type*> prerequisites_;
};
// The type of an array.
static Array_type*
do_import(Import*);
+ // Fill in the fields for a named array type.
+ tree
+ fill_in_array_tree(Gogo*, tree);
+
// Fill in the fields for a named slice type.
tree
- fill_in_tree(Gogo*, tree);
+ fill_in_slice_tree(Gogo*, tree);
+
+ static Type*
+ make_array_type_descriptor_type();
+
+ static Type*
+ make_slice_type_descriptor_type();
protected:
int
tree
get_length_tree(Gogo*);
- Type*
- make_array_type_descriptor_type();
-
- Type*
- make_slice_type_descriptor_type();
-
Expression*
array_type_descriptor(Gogo*, Named_type*);
static Map_type*
do_import(Import*);
+ static Type*
+ make_map_type_descriptor_type();
+
protected:
int
do_traverse(Traverse*);
do_export(Export*) const;
private:
- static Type*
- make_map_type_descriptor_type();
-
// The key type.
Type* key_type_;
// The value type.
static Channel_type*
do_import(Import*);
+ static Type*
+ make_chan_type_descriptor_type();
+
protected:
int
do_traverse(Traverse* traverse)
do_export(Export*) const;
private:
- static Type*
- make_chan_type_descriptor_type();
-
// Whether this channel can send data.
bool may_send_;
// Whether this channel can receive data.
methods_(methods), location_(location)
{ gcc_assert(methods == NULL || !methods->empty()); }
+ // The location where the interface type was defined.
+ source_location
+ location() const
+ { return this->location_; }
+
// Return whether this is an empty interface.
bool
is_empty() const
static Interface_type*
do_import(Import*);
+ // Make a struct for an empty interface type.
+ static tree
+ empty_type_tree(Gogo*);
+
+ // Make a struct for non-empty interface type.
+ static tree
+ non_empty_type_tree(source_location);
+
// Fill in the fields for a named interface type.
tree
fill_in_tree(Gogo*, tree);
+ static Type*
+ make_interface_type_descriptor_type();
+
protected:
int
do_traverse(Traverse*);
do_export(Export*) const;
private:
- static Type*
- make_interface_type_descriptor_type();
-
// The list of methods associated with the interface. This will be
// NULL for the empty interface.
Typed_identifier_list* methods_;
named_object_(named_object), in_function_(NULL), type_(type),
local_methods_(NULL), all_methods_(NULL),
interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
- location_(location), named_tree_(NULL), is_visible_(true),
- is_error_(false), seen_(0)
+ location_(location), named_tree_(NULL), dependencies_(),
+ is_visible_(true), is_error_(false), is_converted_(false),
+ is_circular_(false), seen_(0)
{ }
// Return the associated Named_object. This holds the actual name.
is_builtin() const
{ return this->location_ == BUILTINS_LOCATION; }
+ // Whether this is a circular type: a pointer or function type that
+ // refers to itself, which is not possible in C.
+ bool
+ is_circular() const
+ { return this->is_circular_; }
+
// Return the base type for this type.
Type*
named_base();
bool
named_type_has_hidden_fields(std::string* reason) const;
+ // Note that a type must be converted to the backend representation
+ // before we convert this type.
+ void
+ add_dependency(Named_type* nt)
+ { this->dependencies_.push_back(nt); }
+
// Export the type.
void
export_named_type(Export*, const std::string& name) const;
static void
import_named_type(Import*, Named_type**);
+ // Initial conversion to backend representation.
+ void
+ convert(Gogo*);
+
protected:
int
do_traverse(Traverse* traverse)
do_export(Export*) const;
private:
+ // Create the placeholder during conversion.
+ void
+ create_placeholder(Gogo*);
+
// A mapping from interfaces to the associated interface method
// tables for this type. This maps to a decl.
typedef Unordered_map_hash(const Interface_type*, tree, Type_hash_identical,
// The tree for this type while converting to GENERIC. This is used
// to avoid endless recursion when a named type refers to itself.
tree named_tree_;
+ // A list of types which must be converted to the backend
+ // representation before this type can be converted. This is for
+ // cases like
+ // type S1 { p *S2 }
+ // type S2 { s S1 }
+ // where we can't convert S2 to the backend representation unless we
+ // have converted S1.
+ std::vector<Named_type*> dependencies_;
// Whether this type is visible. This is false if this type was
// created because it was referenced by an imported object, but the
// type itself was not exported. This will always be true for types
bool is_visible_;
// Whether this type is erroneous.
bool is_error_;
+ // Whether this type has been converted to the backend
+ // representation.
+ bool is_converted_;
+ // Whether this is a pointer or function type which refers to the
+ // type itself.
+ bool is_circular_;
// In a recursive operation such as has_hidden_fields, this flag is
// used to prevent infinite recursion when a type refers to itself.
// This is mutable because it is always reset to false when the