Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
6df020c0
Commit
6df020c0
authored
Feb 16, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Fix crash: type T1 struct { F *[1]T2 } where T2 is a struct.
This will become bug417.go. From-SVN: r184299
parent
cc8b9c31
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
352 additions
and
81 deletions
+352
-81
gcc/go/gofrontend/expressions.cc
+2
-2
gcc/go/gofrontend/gogo.cc
+0
-2
gcc/go/gofrontend/types.cc
+324
-62
gcc/go/gofrontend/types.h
+26
-15
No files found.
gcc/go/gofrontend/expressions.cc
View file @
6df020c0
...
...
@@ -522,8 +522,8 @@ Expression::convert_interface_to_interface(Translate_context* context,
// first field is just the type descriptor of the object.
go_assert
(
strcmp
(
IDENTIFIER_POINTER
(
DECL_NAME
(
field
)),
"__type_descriptor"
)
==
0
);
go_assert
(
TREE_TYPE
(
field
)
==
TREE_TYPE
(
rhs_type_descriptor
));
elt
->
value
=
rhs_type_descriptor
;
elt
->
value
=
fold_convert_loc
(
location
.
gcc_location
(),
TREE_TYPE
(
field
),
rhs_type_descriptor
)
;
}
else
{
...
...
gcc/go/gofrontend/gogo.cc
View file @
6df020c0
...
...
@@ -2929,8 +2929,6 @@ Gogo::convert_named_types()
Runtime
::
convert_types
(
this
);
Function_type
::
convert_types
(
this
);
this
->
named_types_are_converted_
=
true
;
}
...
...
gcc/go/gofrontend/types.cc
View file @
6df020c0
...
...
@@ -34,10 +34,28 @@ extern "C"
#include "backend.h"
#include "types.h"
// Forward declarations so that we don't have to make types.h #include
// backend.h.
static
void
get_backend_struct_fields
(
Gogo
*
gogo
,
const
Struct_field_list
*
fields
,
bool
use_placeholder
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
);
static
void
get_backend_slice_fields
(
Gogo
*
gogo
,
Array_type
*
type
,
bool
use_placeholder
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
);
static
void
get_backend_interface_fields
(
Gogo
*
gogo
,
Interface_type
*
type
,
bool
use_placeholder
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
);
// Class Type.
Type
::
Type
(
Type_classification
classification
)
:
classification_
(
classification
),
btype_
(
NULL
),
type_descriptor_var_
(
NULL
)
:
classification_
(
classification
),
btype_is_placeholder_
(
false
),
btype_
(
NULL
),
type_descriptor_var_
(
NULL
)
{
}
...
...
@@ -895,7 +913,11 @@ Btype*
Type
::
get_backend
(
Gogo
*
gogo
)
{
if
(
this
->
btype_
!=
NULL
)
return
this
->
btype_
;
{
if
(
this
->
btype_is_placeholder_
&&
gogo
->
named_types_are_converted
())
this
->
finish_backend
(
gogo
);
return
this
->
btype_
;
}
if
(
this
->
forward_declaration_type
()
!=
NULL
||
this
->
named_type
()
!=
NULL
)
...
...
@@ -966,6 +988,189 @@ Type::get_btype_without_hash(Gogo* gogo)
return
this
->
btype_
;
}
// Get the backend representation of a type without forcing the
// creation of the backend representation of all supporting types.
// This will return a backend type that has the correct size but may
// be incomplete. E.g., a pointer will just be a placeholder pointer,
// and will not contain the final representation of the type to which
// it points. This is used while converting all named types to the
// backend representation, to avoid problems with indirect references
// to types which are not yet complete. When this is called, the
// sizes of all direct references (e.g., a struct field) should be
// known, but the sizes of indirect references (e.g., the type to
// which a pointer points) may not.
Btype
*
Type
::
get_backend_placeholder
(
Gogo
*
gogo
)
{
if
(
gogo
->
named_types_are_converted
())
return
this
->
get_backend
(
gogo
);
if
(
this
->
btype_
!=
NULL
)
return
this
->
btype_
;
Btype
*
bt
;
switch
(
this
->
classification_
)
{
case
TYPE_ERROR
:
case
TYPE_VOID
:
case
TYPE_BOOLEAN
:
case
TYPE_INTEGER
:
case
TYPE_FLOAT
:
case
TYPE_COMPLEX
:
case
TYPE_STRING
:
case
TYPE_NIL
:
// These are simple types that can just be created directly.
return
this
->
get_backend
(
gogo
);
case
TYPE_FUNCTION
:
{
Location
loc
=
this
->
function_type
()
->
location
();
bt
=
gogo
->
backend
()
->
placeholder_pointer_type
(
""
,
loc
,
true
);
}
break
;
case
TYPE_POINTER
:
{
Location
loc
=
Linemap
::
unknown_location
();
bt
=
gogo
->
backend
()
->
placeholder_pointer_type
(
""
,
loc
,
false
);
}
break
;
case
TYPE_STRUCT
:
// We don't have to make the struct itself be a placeholder. We
// are promised that we know the sizes of the struct fields.
// But we may have to use a placeholder for any particular
// struct field.
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_struct_fields
(
gogo
,
this
->
struct_type
()
->
fields
(),
true
,
&
bfields
);
bt
=
gogo
->
backend
()
->
struct_type
(
bfields
);
}
break
;
case
TYPE_ARRAY
:
if
(
this
->
is_slice_type
())
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_slice_fields
(
gogo
,
this
->
array_type
(),
true
,
&
bfields
);
bt
=
gogo
->
backend
()
->
struct_type
(
bfields
);
}
else
{
Btype
*
element
=
this
->
array_type
()
->
get_backend_element
(
gogo
,
true
);
Bexpression
*
len
=
this
->
array_type
()
->
get_backend_length
(
gogo
);
bt
=
gogo
->
backend
()
->
array_type
(
element
,
len
);
}
break
;
case
TYPE_MAP
:
case
TYPE_CHANNEL
:
// All maps and channels have the same backend representation.
return
this
->
get_backend
(
gogo
);
case
TYPE_INTERFACE
:
if
(
this
->
interface_type
()
->
is_empty
())
return
Interface_type
::
get_backend_empty_interface_type
(
gogo
);
else
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_interface_fields
(
gogo
,
this
->
interface_type
(),
true
,
&
bfields
);
bt
=
gogo
->
backend
()
->
struct_type
(
bfields
);
}
break
;
case
TYPE_NAMED
:
case
TYPE_FORWARD
:
// Named types keep track of their own dependencies and manage
// their own placeholders.
return
this
->
get_backend
(
gogo
);
case
TYPE_SINK
:
case
TYPE_CALL_MULTIPLE_RESULT
:
default
:
go_unreachable
();
}
this
->
btype_
=
bt
;
this
->
btype_is_placeholder_
=
true
;
return
bt
;
}
// Complete the backend representation. This is called for a type
// using a placeholder type.
void
Type
::
finish_backend
(
Gogo
*
gogo
)
{
go_assert
(
this
->
btype_
!=
NULL
);
if
(
!
this
->
btype_is_placeholder_
)
return
;
switch
(
this
->
classification_
)
{
case
TYPE_ERROR
:
case
TYPE_VOID
:
case
TYPE_BOOLEAN
:
case
TYPE_INTEGER
:
case
TYPE_FLOAT
:
case
TYPE_COMPLEX
:
case
TYPE_STRING
:
case
TYPE_NIL
:
go_unreachable
();
case
TYPE_FUNCTION
:
{
Btype
*
bt
=
this
->
do_get_backend
(
gogo
);
if
(
!
gogo
->
backend
()
->
set_placeholder_function_type
(
this
->
btype_
,
bt
))
go_assert
(
saw_errors
());
}
break
;
case
TYPE_POINTER
:
{
Btype
*
bt
=
this
->
do_get_backend
(
gogo
);
if
(
!
gogo
->
backend
()
->
set_placeholder_pointer_type
(
this
->
btype_
,
bt
))
go_assert
(
saw_errors
());
}
break
;
case
TYPE_STRUCT
:
// The struct type itself is done, but we have to make sure that
// all the field types are converted.
this
->
struct_type
()
->
finish_backend_fields
(
gogo
);
break
;
case
TYPE_ARRAY
:
// The array type itself is done, but make sure the element type
// is converted.
this
->
array_type
()
->
finish_backend_element
(
gogo
);
break
;
case
TYPE_MAP
:
case
TYPE_CHANNEL
:
go_unreachable
();
case
TYPE_INTERFACE
:
// The interface type itself is done, but make sure the method
// types are converted.
this
->
interface_type
()
->
finish_backend_methods
(
gogo
);
break
;
case
TYPE_NAMED
:
case
TYPE_FORWARD
:
go_unreachable
();
case
TYPE_SINK
:
case
TYPE_CALL_MULTIPLE_RESULT
:
default
:
go_unreachable
();
}
this
->
btype_is_placeholder_
=
false
;
}
// Return a pointer to the type descriptor for this type.
tree
...
...
@@ -2059,7 +2264,8 @@ Type::backend_type_size(Gogo* gogo, unsigned int *psize)
{
if
(
!
this
->
is_backend_type_size_known
(
gogo
))
return
false
;
size_t
size
=
gogo
->
backend
()
->
type_size
(
this
->
get_backend
(
gogo
));
Btype
*
bt
=
this
->
get_backend_placeholder
(
gogo
);
size_t
size
=
gogo
->
backend
()
->
type_size
(
bt
);
*
psize
=
static_cast
<
unsigned
int
>
(
size
);
if
(
*
psize
!=
size
)
return
false
;
...
...
@@ -2074,7 +2280,8 @@ Type::backend_type_align(Gogo* gogo, unsigned int *palign)
{
if
(
!
this
->
is_backend_type_size_known
(
gogo
))
return
false
;
size_t
align
=
gogo
->
backend
()
->
type_alignment
(
this
->
get_backend
(
gogo
));
Btype
*
bt
=
this
->
get_backend_placeholder
(
gogo
);
size_t
align
=
gogo
->
backend
()
->
type_alignment
(
bt
);
*
palign
=
static_cast
<
unsigned
int
>
(
align
);
if
(
*
palign
!=
align
)
return
false
;
...
...
@@ -2089,7 +2296,8 @@ Type::backend_type_field_align(Gogo* gogo, unsigned int *palign)
{
if
(
!
this
->
is_backend_type_size_known
(
gogo
))
return
false
;
size_t
a
=
gogo
->
backend
()
->
type_field_alignment
(
this
->
get_backend
(
gogo
));
Btype
*
bt
=
this
->
get_backend_placeholder
(
gogo
);
size_t
a
=
gogo
->
backend
()
->
type_field_alignment
(
bt
);
*
palign
=
static_cast
<
unsigned
int
>
(
a
);
if
(
*
palign
!=
a
)
return
false
;
...
...
@@ -2712,6 +2920,15 @@ String_type::do_get_backend(Gogo* gogo)
Type
*
b
=
gogo
->
lookup_global
(
"byte"
)
->
type_value
();
Type
*
pb
=
Type
::
make_pointer_type
(
b
);
// We aren't going to get back to this field to finish the
// backend representation, so force it to be finished now.
if
(
!
gogo
->
named_types_are_converted
())
{
pb
->
get_backend_placeholder
(
gogo
);
pb
->
finish_backend
(
gogo
);
}
fields
[
0
].
name
=
"__data"
;
fields
[
0
].
btype
=
pb
->
get_backend
(
gogo
);
fields
[
0
].
location
=
Linemap
::
predeclared_location
();
...
...
@@ -3117,7 +3334,7 @@ Function_type::do_hash_for_method(Gogo* gogo) const
// Get the backend representation for a function type.
Btype
*
Function_type
::
get_function
_backend
(
Gogo
*
gogo
)
Function_type
::
do_get
_backend
(
Gogo
*
gogo
)
{
Backend
::
Btyped_identifier
breceiver
;
if
(
this
->
receiver_
!=
NULL
)
...
...
@@ -3169,46 +3386,6 @@ Function_type::get_function_backend(Gogo* gogo)
this
->
location
());
}
// A hash table mapping function types to their backend placeholders.
Function_type
::
Placeholders
Function_type
::
placeholders
;
// Get the backend representation for a function type. If we are
// still converting types, and this types has multiple results, return
// a placeholder instead. We do this because for multiple results we
// build a struct, and we need to make sure that all the types in the
// struct are valid before we create the struct.
Btype
*
Function_type
::
do_get_backend
(
Gogo
*
gogo
)
{
if
(
!
gogo
->
named_types_are_converted
()
&&
this
->
results_
!=
NULL
&&
this
->
results_
->
size
()
>
1
)
{
Btype
*
placeholder
=
gogo
->
backend
()
->
placeholder_pointer_type
(
""
,
this
->
location
(),
true
);
Function_type
::
placeholders
.
push_back
(
std
::
make_pair
(
this
,
placeholder
));
return
placeholder
;
}
return
this
->
get_function_backend
(
gogo
);
}
// Convert function types after all named types are converted.
void
Function_type
::
convert_types
(
Gogo
*
gogo
)
{
for
(
Placeholders
::
const_iterator
p
=
Function_type
::
placeholders
.
begin
();
p
!=
Function_type
::
placeholders
.
end
();
++
p
)
{
Btype
*
bt
=
p
->
first
->
get_function_backend
(
gogo
);
if
(
!
gogo
->
backend
()
->
set_placeholder_function_type
(
p
->
second
,
bt
))
go_assert
(
saw_errors
());
}
}
// The type of a function type descriptor.
Type
*
...
...
@@ -4346,6 +4523,7 @@ Struct_type::method_function(const std::string& name, bool* is_ambiguous) const
static
void
get_backend_struct_fields
(
Gogo
*
gogo
,
const
Struct_field_list
*
fields
,
bool
use_placeholder
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
)
{
bfields
->
resize
(
fields
->
size
());
...
...
@@ -4355,7 +4533,9 @@ get_backend_struct_fields(Gogo* gogo, const Struct_field_list* fields,
++
p
,
++
i
)
{
(
*
bfields
)[
i
].
name
=
Gogo
::
unpack_hidden_name
(
p
->
field_name
());
(
*
bfields
)[
i
].
btype
=
p
->
type
()
->
get_backend
(
gogo
);
(
*
bfields
)[
i
].
btype
=
(
use_placeholder
?
p
->
type
()
->
get_backend_placeholder
(
gogo
)
:
p
->
type
()
->
get_backend
(
gogo
));
(
*
bfields
)[
i
].
location
=
p
->
location
();
}
go_assert
(
i
==
fields
->
size
());
...
...
@@ -4367,10 +4547,25 @@ Btype*
Struct_type
::
do_get_backend
(
Gogo
*
gogo
)
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_struct_fields
(
gogo
,
this
->
fields_
,
&
bfields
);
get_backend_struct_fields
(
gogo
,
this
->
fields_
,
false
,
&
bfields
);
return
gogo
->
backend
()
->
struct_type
(
bfields
);
}
// Finish the backend representation of the fields of a struct.
void
Struct_type
::
finish_backend_fields
(
Gogo
*
gogo
)
{
const
Struct_field_list
*
fields
=
this
->
fields_
;
if
(
fields
!=
NULL
)
{
for
(
Struct_field_list
::
const_iterator
p
=
fields
->
begin
();
p
!=
fields
->
end
();
++
p
)
p
->
type
()
->
get_backend
(
gogo
);
}
}
// The type of a struct type descriptor.
Type
*
...
...
@@ -4776,8 +4971,8 @@ Struct_type::backend_field_offset(Gogo* gogo, unsigned int index,
{
if
(
!
this
->
is_backend_type_size_known
(
gogo
))
return
false
;
size_t
offset
=
gogo
->
backend
()
->
type_field_offset
(
this
->
get_backend
(
gogo
),
index
);
Btype
*
bt
=
this
->
get_backend_placeholder
(
gogo
);
size_t
offset
=
gogo
->
backend
()
->
type_field_offset
(
bt
,
index
);
*
poffset
=
static_cast
<
unsigned
int
>
(
offset
);
if
(
*
poffset
!=
offset
)
return
false
;
...
...
@@ -5295,13 +5490,15 @@ Array_type::get_length_tree(Gogo* gogo)
// size which does not fit in int.
static
void
get_backend_slice_fields
(
Gogo
*
gogo
,
Array_type
*
type
,
get_backend_slice_fields
(
Gogo
*
gogo
,
Array_type
*
type
,
bool
use_placeholder
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
)
{
bfields
->
resize
(
3
);
Type
*
pet
=
Type
::
make_pointer_type
(
type
->
element_type
());
Btype
*
pbet
=
pet
->
get_backend
(
gogo
);
Btype
*
pbet
=
(
use_placeholder
?
pet
->
get_backend_placeholder
(
gogo
)
:
pet
->
get_backend
(
gogo
));
Location
ploc
=
Linemap
::
predeclared_location
();
Backend
::
Btyped_identifier
*
p
=
&
(
*
bfields
)[
0
];
...
...
@@ -5333,12 +5530,12 @@ Array_type::do_get_backend(Gogo* gogo)
if
(
this
->
length_
==
NULL
)
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_slice_fields
(
gogo
,
this
,
&
bfields
);
get_backend_slice_fields
(
gogo
,
this
,
false
,
&
bfields
);
return
gogo
->
backend
()
->
struct_type
(
bfields
);
}
else
{
Btype
*
element
=
this
->
get_backend_element
(
gogo
);
Btype
*
element
=
this
->
get_backend_element
(
gogo
,
false
);
Bexpression
*
len
=
this
->
get_backend_length
(
gogo
);
return
gogo
->
backend
()
->
array_type
(
element
,
len
);
}
...
...
@@ -5347,9 +5544,12 @@ Array_type::do_get_backend(Gogo* gogo)
// Return the backend representation of the element type.
Btype
*
Array_type
::
get_backend_element
(
Gogo
*
gogo
)
Array_type
::
get_backend_element
(
Gogo
*
gogo
,
bool
use_placeholder
)
{
return
this
->
element_type_
->
get_backend
(
gogo
);
if
(
use_placeholder
)
return
this
->
element_type_
->
get_backend_placeholder
(
gogo
);
else
return
this
->
element_type_
->
get_backend
(
gogo
);
}
// Return the backend representation of the length.
...
...
@@ -5360,6 +5560,22 @@ Array_type::get_backend_length(Gogo* gogo)
return
tree_to_expr
(
this
->
get_length_tree
(
gogo
));
}
// Finish backend representation of the array.
void
Array_type
::
finish_backend_element
(
Gogo
*
gogo
)
{
Type
*
et
=
this
->
array_type
()
->
element_type
();
et
->
get_backend
(
gogo
);
if
(
this
->
is_slice_type
())
{
// This relies on the fact that we always use the same
// structure for a pointer to any given type.
Type
*
pet
=
Type
::
make_pointer_type
(
et
);
pet
->
get_backend
(
gogo
);
}
}
// Return a tree for a pointer to the values in ARRAY.
tree
...
...
@@ -6652,6 +6868,7 @@ Interface_type::get_backend_empty_interface_type(Gogo* gogo)
static
void
get_backend_interface_fields
(
Gogo
*
gogo
,
Interface_type
*
type
,
bool
use_placeholder
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
)
{
Location
loc
=
type
->
location
();
...
...
@@ -6670,7 +6887,9 @@ get_backend_interface_fields(Gogo* gogo, Interface_type* type,
++
p
,
++
i
)
{
mfields
[
i
].
name
=
Gogo
::
unpack_hidden_name
(
p
->
name
());
mfields
[
i
].
btype
=
p
->
type
()
->
get_backend
(
gogo
);
mfields
[
i
].
btype
=
(
use_placeholder
?
p
->
type
()
->
get_backend_placeholder
(
gogo
)
:
p
->
type
()
->
get_backend
(
gogo
));
mfields
[
i
].
location
=
loc
;
// Sanity check: the names should be sorted.
go_assert
(
p
->
name
()
>
last_name
);
...
...
@@ -6710,7 +6929,7 @@ Interface_type::do_get_backend(Gogo* gogo)
this
->
interface_btype_
=
gogo
->
backend
()
->
placeholder_struct_type
(
""
,
this
->
location_
);
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_interface_fields
(
gogo
,
this
,
&
bfields
);
get_backend_interface_fields
(
gogo
,
this
,
false
,
&
bfields
);
if
(
!
gogo
->
backend
()
->
set_placeholder_struct_type
(
this
->
interface_btype_
,
bfields
))
this
->
interface_btype_
=
gogo
->
backend
()
->
error_type
();
...
...
@@ -6718,6 +6937,24 @@ Interface_type::do_get_backend(Gogo* gogo)
}
}
// Finish the backend representation of the methods.
void
Interface_type
::
finish_backend_methods
(
Gogo
*
gogo
)
{
if
(
!
this
->
interface_type
()
->
is_empty
())
{
const
Typed_identifier_list
*
methods
=
this
->
methods
();
if
(
methods
!=
NULL
)
{
for
(
Typed_identifier_list
::
const_iterator
p
=
methods
->
begin
();
p
!=
methods
->
end
();
++
p
)
p
->
type
()
->
get_backend
(
gogo
);
}
}
}
// The type of an interface type descriptor.
Type
*
...
...
@@ -7751,7 +7988,7 @@ Named_type::convert(Gogo* gogo)
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_struct_fields
(
gogo
,
base
->
struct_type
()
->
fields
(),
&
bfields
);
true
,
&
bfields
);
if
(
!
gogo
->
backend
()
->
set_placeholder_struct_type
(
bt
,
bfields
))
bt
=
gogo
->
backend
()
->
error_type
();
}
...
...
@@ -7761,7 +7998,7 @@ Named_type::convert(Gogo* gogo)
// Slice types were completed in create_placeholder.
if
(
!
base
->
is_slice_type
())
{
Btype
*
bet
=
base
->
array_type
()
->
get_backend_element
(
gogo
);
Btype
*
bet
=
base
->
array_type
()
->
get_backend_element
(
gogo
,
true
);
Bexpression
*
blen
=
base
->
array_type
()
->
get_backend_length
(
gogo
);
if
(
!
gogo
->
backend
()
->
set_placeholder_array_type
(
bt
,
bet
,
blen
))
bt
=
gogo
->
backend
()
->
error_type
();
...
...
@@ -7893,7 +8130,7 @@ Named_type::create_placeholder(Gogo* gogo)
// because we can fill them in completely here with the final
// size.
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_slice_fields
(
gogo
,
base
->
array_type
(),
&
bfields
);
get_backend_slice_fields
(
gogo
,
base
->
array_type
(),
true
,
&
bfields
);
if
(
!
gogo
->
backend
()
->
set_placeholder_struct_type
(
bt
,
bfields
))
this
->
named_btype_
=
gogo
->
backend
()
->
error_type
();
}
...
...
@@ -7904,7 +8141,8 @@ Named_type::create_placeholder(Gogo* gogo)
// because we can fill them in completely here with the final
// size.
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_interface_fields
(
gogo
,
base
->
interface_type
(),
&
bfields
);
get_backend_interface_fields
(
gogo
,
base
->
interface_type
(),
true
,
&
bfields
);
if
(
!
gogo
->
backend
()
->
set_placeholder_struct_type
(
bt
,
bfields
))
this
->
named_btype_
=
gogo
->
backend
()
->
error_type
();
}
...
...
@@ -7963,9 +8201,33 @@ Named_type::do_get_backend(Gogo* gogo)
case
TYPE_NIL
:
case
TYPE_MAP
:
case
TYPE_CHANNEL
:
return
bt
;
case
TYPE_STRUCT
:
if
(
!
this
->
seen_in_get_backend_
)
{
this
->
seen_in_get_backend_
=
true
;
base
->
struct_type
()
->
finish_backend_fields
(
gogo
);
this
->
seen_in_get_backend_
=
false
;
}
return
bt
;
case
TYPE_ARRAY
:
if
(
!
this
->
seen_in_get_backend_
)
{
this
->
seen_in_get_backend_
=
true
;
base
->
array_type
()
->
finish_backend_element
(
gogo
);
this
->
seen_in_get_backend_
=
false
;
}
return
bt
;
case
TYPE_INTERFACE
:
if
(
!
this
->
seen_in_get_backend_
)
{
this
->
seen_in_get_backend_
=
true
;
base
->
interface_type
()
->
finish_backend_methods
(
gogo
);
this
->
seen_in_get_backend_
=
false
;
}
return
bt
;
case
TYPE_FUNCTION
:
...
...
gcc/go/gofrontend/types.h
View file @
6df020c0
...
...
@@ -852,6 +852,16 @@ class Type
Btype
*
get_backend
(
Gogo
*
);
// Return a placeholder for the backend representation of the type.
// This will return a type of the correct size, but for which some
// of the fields may still need to be completed.
Btype
*
get_backend_placeholder
(
Gogo
*
);
// Finish the backend representation of a placeholder.
void
finish_backend
(
Gogo
*
);
// Build a type descriptor entry for this type. Return a pointer to
// it. The location is the location which causes us to need the
// entry.
...
...
@@ -1179,6 +1189,9 @@ class Type
// The type classification.
Type_classification
classification_
;
// Whether btype_ is a placeholder type used while named types are
// being converted.
bool
btype_is_placeholder_
;
// The backend representation of the type, once it has been
// determined.
Btype
*
btype_
;
...
...
@@ -1730,10 +1743,6 @@ class Function_type : public Type
Function_type
*
copy_with_receiver
(
Type
*
)
const
;
// Finishing converting function types.
static
void
convert_types
(
Gogo
*
);
static
Type
*
make_function_type_descriptor_type
();
...
...
@@ -1773,16 +1782,6 @@ class Function_type : public Type
type_descriptor_params
(
Type
*
,
const
Typed_identifier
*
,
const
Typed_identifier_list
*
);
Btype
*
get_function_backend
(
Gogo
*
);
// A list of function types with multiple results and their
// placeholder backend representations, used to postpone building
// the structs we use for multiple results until all types are
// converted.
typedef
std
::
vector
<
std
::
pair
<
Function_type
*
,
Btype
*>
>
Placeholders
;
static
Placeholders
placeholders
;
// The receiver name and type. This will be NULL for a normal
// function, non-NULL for a method.
Typed_identifier
*
receiver_
;
...
...
@@ -2079,6 +2078,10 @@ class Struct_type : public Type
bool
backend_field_offset
(
Gogo
*
,
unsigned
int
index
,
unsigned
int
*
poffset
);
// Finish the backend representation of all the fields.
void
finish_backend_fields
(
Gogo
*
);
// Import a struct type.
static
Struct_type
*
do_import
(
Import
*
);
...
...
@@ -2193,12 +2196,16 @@ class Array_type : public Type
// Return the backend representation of the element type.
Btype
*
get_backend_element
(
Gogo
*
);
get_backend_element
(
Gogo
*
,
bool
use_placeholder
);
// Return the backend representation of the length.
Bexpression
*
get_backend_length
(
Gogo
*
);
// Finish the backend representation of the element type.
void
finish_backend_element
(
Gogo
*
);
static
Type
*
make_array_type_descriptor_type
();
...
...
@@ -2521,6 +2528,10 @@ class Interface_type : public Type
static
Btype
*
get_backend_empty_interface_type
(
Gogo
*
);
// Finish the backend representation of the method types.
void
finish_backend_methods
(
Gogo
*
);
static
Type
*
make_interface_type_descriptor_type
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment