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
da9e0b98
Commit
da9e0b98
authored
May 06, 2011
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use backend interface for interface types.
From-SVN: r173469
parent
3d528853
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
114 deletions
+91
-114
gcc/go/gofrontend/types.cc
+89
-104
gcc/go/gofrontend/types.h
+2
-10
No files found.
gcc/go/gofrontend/types.cc
View file @
da9e0b98
...
...
@@ -6003,124 +6003,99 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
return
true
;
}
// Return a tree for an interface type. An interface is a pointer to
// a struct. The struct has three fields. The first field is a
// pointer to the type descriptor for the dynamic type of the object.
// The second field is a pointer to a table of methods for the
// interface to be used with the object. The third field is the value
// of the object itself.
// Return the backend representation of the empty interface type. We
// use the same struct for all empty interfaces.
tree
Interface_type
::
do_get_tre
e
(
Gogo
*
gogo
)
Btype
*
Interface_type
::
get_backend_empty_interface_typ
e
(
Gogo
*
gogo
)
{
if
(
this
->
methods_
==
NULL
)
return
Interface_type
::
empty_type_tree
(
gogo
);
else
static
Btype
*
empty_interface_type
;
if
(
empty_interface_type
==
NULL
)
{
tree
t
=
Interface_type
::
non_empty_type_tree
(
this
->
location_
);
return
this
->
fill_in_tree
(
gogo
,
t
);
}
}
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
(
2
);
// Return a singleton struct for an empty interface type. We use the
// same type for all empty interfaces. This lets us assign them to
// each other directly without triggering GIMPLE type errors.
Type
*
pdt
=
Type
::
make_type_descriptor_ptr_type
();
bfields
[
0
].
name
=
"__type_descriptor"
;
bfields
[
0
].
btype
=
tree_to_type
(
pdt
->
get_tree
(
gogo
));
bfields
[
0
].
location
=
UNKNOWN_LOCATION
;
tree
Interface_type
::
empty_type_tree
(
Gogo
*
gogo
)
{
static
tree
empty_interface
;
if
(
empty_interface
!=
NULL_TREE
)
return
empty_interface
;
Type
*
vt
=
Type
::
make_pointer_type
(
Type
::
make_void_type
());
bfields
[
1
].
name
=
"__object"
;
bfields
[
1
].
btype
=
tree_to_type
(
vt
->
get_tree
(
gogo
));
bfields
[
1
].
location
=
UNKNOWN_LOCATION
;
tree
dtype
=
Type
::
make_type_descriptor_type
()
->
get_tree
(
gogo
);
dtype
=
build_pointer_type
(
build_qualified_type
(
dtype
,
TYPE_QUAL_CONST
));
return
Gogo
::
builtin_struct
(
&
empty_interface
,
"__go_empty_interface"
,
NULL_TREE
,
2
,
"__type_descriptor"
,
dtype
,
"__object"
,
ptr_type_node
);
empty_interface_type
=
gogo
->
backend
()
->
struct_type
(
bfields
);
}
return
empty_interface_type
;
}
// Return a new struct for a non-empty interface type. The correct
// values are filled in by fill_in_tree.
// Return the fields of a non-empty interface type. This is not
// declared in types.h so that types.h doesn't have to #include
// backend.h.
tree
Interface_type
::
non_empty_type_tree
(
source_location
location
)
static
void
get_backend_interface_fields
(
Gogo
*
gogo
,
Interface_type
*
type
,
std
::
vector
<
Backend
::
Btyped_identifier
>*
bfields
)
{
tree
ret
=
make_node
(
RECORD_TYPE
);
source_location
loc
=
type
->
location
();
std
::
vector
<
Backend
::
Btyped_identifier
>
mfields
(
type
->
methods
()
->
size
()
+
1
);
tree
field_trees
=
NULL_TREE
;
tree
*
pp
=
&
field_trees
;
Type
*
pdt
=
Type
::
make_type_descriptor_ptr_type
();
mfields
[
0
].
name
=
"__type_descriptor"
;
mfields
[
0
].
btype
=
tree_to_type
(
pdt
->
get_tree
(
gogo
));
mfields
[
0
].
location
=
loc
;
tree
name_tree
=
get_identifier
(
"__methods"
);
tree
field
=
build_decl
(
location
,
FIELD_DECL
,
name_tree
,
ptr_type_node
);
DECL_CONTEXT
(
field
)
=
ret
;
*
pp
=
field
;
pp
=
&
DECL_CHAIN
(
field
);
std
::
string
last_name
=
""
;
size_t
i
=
1
;
for
(
Typed_identifier_list
::
const_iterator
p
=
type
->
methods
()
->
begin
();
p
!=
type
->
methods
()
->
end
();
++
p
,
++
i
)
{
mfields
[
i
].
name
=
Gogo
::
unpack_hidden_name
(
p
->
name
());
mfields
[
i
].
btype
=
tree_to_type
(
p
->
type
()
->
get_tree
(
gogo
));
mfields
[
i
].
location
=
loc
;
// Sanity check: the names should be sorted.
go_assert
(
p
->
name
()
>
last_name
);
last_name
=
p
->
name
();
}
name_tree
=
get_identifier
(
"__object"
);
field
=
build_decl
(
location
,
FIELD_DECL
,
name_tree
,
ptr_type_node
);
DECL_CONTEXT
(
field
)
=
ret
;
*
pp
=
field
;
Btype
*
methods
=
gogo
->
backend
()
->
struct_type
(
mfields
);
TYPE_FIELDS
(
ret
)
=
field_trees
;
bfields
->
resize
(
2
)
;
layout_type
(
ret
);
(
*
bfields
)[
0
].
name
=
"__methods"
;
(
*
bfields
)[
0
].
btype
=
gogo
->
backend
()
->
pointer_type
(
methods
);
(
*
bfields
)[
0
].
location
=
loc
;
return
ret
;
Type
*
vt
=
Type
::
make_pointer_type
(
Type
::
make_void_type
());
(
*
bfields
)[
1
].
name
=
"__object"
;
(
*
bfields
)[
1
].
btype
=
tree_to_type
(
vt
->
get_tree
(
gogo
));
(
*
bfields
)[
1
].
location
=
UNKNOWN_LOCATION
;
}
// Fill in the tree for an interface type. This is used for named
// interface types.
// Return a tree for an interface type. An interface is a pointer to
// a struct. The struct has three fields. The first field is a
// pointer to the type descriptor for the dynamic type of the object.
// The second field is a pointer to a table of methods for the
// interface to be used with the object. The third field is the value
// of the object itself.
tree
Interface_type
::
fill_in_tree
(
Gogo
*
gogo
,
tree
type
)
Interface_type
::
do_get_tree
(
Gogo
*
gogo
)
{
go_assert
(
this
->
methods_
!=
NULL
);
// Build the type of the table of methods.
tree
method_table
=
make_node
(
RECORD_TYPE
);
// The first field is a pointer to the type descriptor.
tree
name_tree
=
get_identifier
(
"__type_descriptor"
);
tree
dtype
=
Type
::
make_type_descriptor_type
()
->
get_tree
(
gogo
);
dtype
=
build_pointer_type
(
build_qualified_type
(
dtype
,
TYPE_QUAL_CONST
));
tree
field
=
build_decl
(
this
->
location_
,
FIELD_DECL
,
name_tree
,
dtype
);
DECL_CONTEXT
(
field
)
=
method_table
;
TYPE_FIELDS
(
method_table
)
=
field
;
std
::
string
last_name
=
""
;
tree
*
pp
=
&
DECL_CHAIN
(
field
);
for
(
Typed_identifier_list
::
const_iterator
p
=
this
->
methods_
->
begin
();
p
!=
this
->
methods_
->
end
();
++
p
)
if
(
this
->
methods_
==
NULL
)
{
std
::
string
name
=
Gogo
::
unpack_hidden_name
(
p
->
name
());
name_tree
=
get_identifier_with_length
(
name
.
data
(),
name
.
length
());
tree
field_type
=
p
->
type
()
->
get_tree
(
gogo
);
if
(
field_type
==
error_mark_node
)
return
error_mark_node
;
field
=
build_decl
(
this
->
location_
,
FIELD_DECL
,
name_tree
,
field_type
);
DECL_CONTEXT
(
field
)
=
method_table
;
*
pp
=
field
;
pp
=
&
DECL_CHAIN
(
field
);
// Sanity check: the names should be sorted.
go_assert
(
p
->
name
()
>
last_name
);
last_name
=
p
->
name
();
Btype
*
bt
=
Interface_type
::
get_backend_empty_interface_type
(
gogo
);
return
type_to_tree
(
bt
);
}
else
{
std
::
vector
<
Backend
::
Btyped_identifier
>
bfields
;
get_backend_interface_fields
(
gogo
,
this
,
&
bfields
);
Btype
*
bt
=
gogo
->
backend
()
->
struct_type
(
bfields
);
return
type_to_tree
(
bt
);
}
layout_type
(
method_table
);
// Update the type of the __methods field from a generic pointer to
// a pointer to the method table.
field
=
TYPE_FIELDS
(
type
);
go_assert
(
strcmp
(
IDENTIFIER_POINTER
(
DECL_NAME
(
field
)),
"__methods"
)
==
0
);
TREE_TYPE
(
field
)
=
build_pointer_type
(
method_table
);
return
type
;
}
// Initialization value.
...
...
@@ -7089,6 +7064,7 @@ Named_type::convert(Gogo* gogo)
break
;
case
TYPE_ARRAY
:
// Slice types were completed in create_placeholder.
if
(
!
base
->
is_open_array_type
())
{
Btype
*
bet
=
base
->
array_type
()
->
get_backend_element
(
gogo
);
...
...
@@ -7099,11 +7075,7 @@ Named_type::convert(Gogo* gogo)
break
;
case
TYPE_INTERFACE
:
if
(
!
base
->
interface_type
()
->
is_empty
())
{
tree
t
=
type_to_tree
(
bt
);
bt
=
tree_to_type
(
base
->
interface_type
()
->
fill_in_tree
(
gogo
,
t
));
}
// Interface types were completed in create_placeholder.
break
;
case
TYPE_ERROR
:
...
...
@@ -7194,11 +7166,12 @@ Named_type::create_placeholder(Gogo* gogo)
case
TYPE_INTERFACE
:
if
(
base
->
interface_type
()
->
is_empty
())
bt
=
tree_to_type
(
Interface_type
::
empty_type_tree
(
gogo
)
);
bt
=
Interface_type
::
get_backend_empty_interface_type
(
gogo
);
else
{
source_location
loc
=
base
->
interface_type
()
->
location
();
bt
=
tree_to_type
(
Interface_type
::
non_empty_type_tree
(
loc
));
bt
=
gogo
->
backend
()
->
placeholder_struct_type
(
this
->
name
(),
this
->
location_
);
set_name
=
false
;
}
break
;
...
...
@@ -7218,12 +7191,24 @@ Named_type::create_placeholder(Gogo* gogo)
if
(
base
->
is_open_array_type
())
{
// We do not record slices as dependencies of other types,
// because we can fill them in completely here.
// 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
);
if
(
!
gogo
->
backend
()
->
set_placeholder_struct_type
(
bt
,
bfields
))
this
->
named_btype_
=
gogo
->
backend
()
->
error_type
();
}
else
if
(
base
->
interface_type
()
!=
NULL
&&
!
base
->
interface_type
()
->
is_empty
())
{
// We do not record interfaces as dependencies of other types,
// 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
);
if
(
!
gogo
->
backend
()
->
set_placeholder_struct_type
(
bt
,
bfields
))
this
->
named_btype_
=
gogo
->
backend
()
->
error_type
();
}
}
// Get a tree for a named type.
...
...
gcc/go/gofrontend/types.h
View file @
da9e0b98
...
...
@@ -2369,16 +2369,8 @@ class Interface_type : public 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
Btype
*
get_backend_empty_interface_type
(
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