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
0efaba3c
Commit
0efaba3c
authored
Sep 22, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Fix unnamed struct type converted to interface type.
From-SVN: r191627
parent
bab51373
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
135 additions
and
46 deletions
+135
-46
gcc/go/gofrontend/expressions.cc
+10
-4
gcc/go/gofrontend/gogo-tree.cc
+12
-4
gcc/go/gofrontend/gogo.cc
+18
-4
gcc/go/gofrontend/gogo.h
+1
-1
gcc/go/gofrontend/types.cc
+64
-27
gcc/go/gofrontend/types.h
+30
-6
No files found.
gcc/go/gofrontend/expressions.cc
View file @
0efaba3c
...
...
@@ -293,19 +293,25 @@ Expression::convert_type_to_interface(Translate_context* context,
// object type: a list of function pointers for each interface
// method.
Named_type
*
rhs_named_type
=
rhs_type
->
named_type
();
Struct_type
*
rhs_struct_type
=
rhs_type
->
struct_type
();
bool
is_pointer
=
false
;
if
(
rhs_named_type
==
NULL
)
if
(
rhs_named_type
==
NULL
&&
rhs_struct_type
==
NULL
)
{
rhs_named_type
=
rhs_type
->
deref
()
->
named_type
();
rhs_struct_type
=
rhs_type
->
deref
()
->
struct_type
();
is_pointer
=
true
;
}
tree
method_table
;
if
(
rhs_named_type
==
NULL
)
method_table
=
null_pointer_node
;
else
if
(
rhs_named_type
!=
NULL
)
method_table
=
rhs_named_type
->
interface_method_table
(
gogo
,
lhs_interface_type
,
is_pointer
);
else
if
(
rhs_struct_type
!=
NULL
)
method_table
=
rhs_struct_type
->
interface_method_table
(
gogo
,
lhs_interface_type
,
is_pointer
);
else
method_table
=
null_pointer_node
;
first_field_value
=
fold_convert_loc
(
location
.
gcc_location
(),
const_ptr_type_node
,
method_table
);
}
...
...
gcc/go/gofrontend/gogo-tree.cc
View file @
0efaba3c
...
...
@@ -2128,8 +2128,7 @@ Gogo::slice_constructor(tree slice_type_tree, tree values, tree count,
tree
Gogo
::
interface_method_table_for_type
(
const
Interface_type
*
interface
,
Named_type
*
type
,
bool
is_pointer
)
Type
*
type
,
bool
is_pointer
)
{
const
Typed_identifier_list
*
interface_methods
=
interface
->
methods
();
go_assert
(
!
interface_methods
->
empty
());
...
...
@@ -2158,7 +2157,9 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
// interface. If the interface has hidden methods, and the named
// type is defined in a different package, then the interface
// conversion table will be defined by that other package.
if
(
has_hidden_methods
&&
type
->
named_object
()
->
package
()
!=
NULL
)
if
(
has_hidden_methods
&&
type
->
named_type
()
!=
NULL
&&
type
->
named_type
()
->
named_object
()
->
package
()
!=
NULL
)
{
tree
array_type
=
build_array_type
(
const_ptr_type_node
,
NULL
);
tree
decl
=
build_decl
(
BUILTINS_LOCATION
,
VAR_DECL
,
id
,
array_type
);
...
...
@@ -2187,13 +2188,20 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
Linemap
::
predeclared_location
());
elt
->
value
=
fold_convert
(
const_ptr_type_node
,
tdp
);
Named_type
*
nt
=
type
->
named_type
();
Struct_type
*
st
=
type
->
struct_type
();
go_assert
(
nt
!=
NULL
||
st
!=
NULL
);
size_t
i
=
1
;
for
(
Typed_identifier_list
::
const_iterator
p
=
interface_methods
->
begin
();
p
!=
interface_methods
->
end
();
++
p
,
++
i
)
{
bool
is_ambiguous
;
Method
*
m
=
type
->
method_function
(
p
->
name
(),
&
is_ambiguous
);
Method
*
m
;
if
(
nt
!=
NULL
)
m
=
nt
->
method_function
(
p
->
name
(),
&
is_ambiguous
);
else
m
=
st
->
method_function
(
p
->
name
(),
&
is_ambiguous
);
go_assert
(
m
!=
NULL
);
Named_object
*
no
=
m
->
named_object
();
...
...
gcc/go/gofrontend/gogo.cc
View file @
0efaba3c
...
...
@@ -2872,7 +2872,8 @@ int
Build_method_tables
::
type
(
Type
*
type
)
{
Named_type
*
nt
=
type
->
named_type
();
if
(
nt
!=
NULL
)
Struct_type
*
st
=
type
->
struct_type
();
if
(
nt
!=
NULL
||
st
!=
NULL
)
{
for
(
std
::
vector
<
Interface_type
*>::
const_iterator
p
=
this
->
interfaces_
.
begin
();
...
...
@@ -2882,10 +2883,23 @@ Build_method_tables::type(Type* type)
// We ask whether a pointer to the named type implements the
// interface, because a pointer can implement more methods
// than a value.
if
(
(
*
p
)
->
implements_interface
(
Type
::
make_pointer_type
(
nt
),
NULL
)
)
if
(
nt
!=
NULL
)
{
nt
->
interface_method_table
(
this
->
gogo_
,
*
p
,
false
);
nt
->
interface_method_table
(
this
->
gogo_
,
*
p
,
true
);
if
((
*
p
)
->
implements_interface
(
Type
::
make_pointer_type
(
nt
),
NULL
))
{
nt
->
interface_method_table
(
this
->
gogo_
,
*
p
,
false
);
nt
->
interface_method_table
(
this
->
gogo_
,
*
p
,
true
);
}
}
else
{
if
((
*
p
)
->
implements_interface
(
Type
::
make_pointer_type
(
st
),
NULL
))
{
st
->
interface_method_table
(
this
->
gogo_
,
*
p
,
false
);
st
->
interface_method_table
(
this
->
gogo_
,
*
p
,
true
);
}
}
}
}
...
...
gcc/go/gofrontend/gogo.h
View file @
0efaba3c
...
...
@@ -574,7 +574,7 @@ class Gogo
// Build an interface method table for a type: a list of function
// pointers, one for each interface method. This returns a decl.
tree
interface_method_table_for_type
(
const
Interface_type
*
,
Named_t
ype
*
,
interface_method_table_for_type
(
const
Interface_type
*
,
T
ype
*
,
bool
is_pointer
);
// Return a tree which allocate SIZE bytes to hold values of type
...
...
gcc/go/gofrontend/types.cc
View file @
0efaba3c
...
...
@@ -4554,6 +4554,20 @@ Struct_type::method_function(const std::string& name, bool* is_ambiguous) const
return
Type
::
method_function
(
this
->
all_methods_
,
name
,
is_ambiguous
);
}
// Return a pointer to the interface method table for this type for
// the interface INTERFACE. IS_POINTER is true if this is for a
// pointer to THIS.
tree
Struct_type
::
interface_method_table
(
Gogo
*
gogo
,
const
Interface_type
*
interface
,
bool
is_pointer
)
{
return
Type
::
interface_method_table
(
gogo
,
this
,
interface
,
is_pointer
,
&
this
->
interface_method_tables_
,
&
this
->
pointer_interface_method_tables_
);
}
// Convert struct fields to the backend representation. This is not
// declared in types.h so that types.h doesn't have to #include
// backend.h.
...
...
@@ -7182,7 +7196,17 @@ Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
if
(
!
p
->
name
().
empty
())
{
std
::
string
n
=
Gogo
::
unpack_hidden_name
(
p
->
name
());
std
::
string
n
;
if
(
!
Gogo
::
is_hidden_name
(
p
->
name
()))
n
=
p
->
name
();
else
{
n
=
"."
;
std
::
string
pkgpath
=
Gogo
::
hidden_name_pkgpath
(
p
->
name
());
n
.
append
(
Gogo
::
pkgpath_for_symbol
(
pkgpath
));
n
.
append
(
1
,
'.'
);
n
.
append
(
Gogo
::
unpack_hidden_name
(
p
->
name
()));
}
char
buf
[
20
];
snprintf
(
buf
,
sizeof
buf
,
"%u_"
,
static_cast
<
unsigned
int
>
(
n
.
length
()));
...
...
@@ -7735,32 +7759,9 @@ tree
Named_type
::
interface_method_table
(
Gogo
*
gogo
,
const
Interface_type
*
interface
,
bool
is_pointer
)
{
go_assert
(
!
interface
->
is_empty
());
Interface_method_tables
**
pimt
=
(
is_pointer
?
&
this
->
interface_method_tables_
:
&
this
->
pointer_interface_method_tables_
);
if
(
*
pimt
==
NULL
)
*
pimt
=
new
Interface_method_tables
(
5
);
std
::
pair
<
const
Interface_type
*
,
tree
>
val
(
interface
,
NULL_TREE
);
std
::
pair
<
Interface_method_tables
::
iterator
,
bool
>
ins
=
(
*
pimt
)
->
insert
(
val
);
if
(
ins
.
second
)
{
// This is a new entry in the hash table.
go_assert
(
ins
.
first
->
second
==
NULL_TREE
);
ins
.
first
->
second
=
gogo
->
interface_method_table_for_type
(
interface
,
this
,
is_pointer
);
}
tree
decl
=
ins
.
first
->
second
;
if
(
decl
==
error_mark_node
)
return
error_mark_node
;
go_assert
(
decl
!=
NULL_TREE
&&
TREE_CODE
(
decl
)
==
VAR_DECL
);
return
build_fold_addr_expr
(
decl
);
return
Type
::
interface_method_table
(
gogo
,
this
,
interface
,
is_pointer
,
&
this
->
interface_method_tables_
,
&
this
->
pointer_interface_method_tables_
);
}
// Return whether a named type has any hidden fields.
...
...
@@ -8944,6 +8945,42 @@ Type::method_function(const Methods* methods, const std::string& name,
return
m
;
}
// Return a pointer to the interface method table for TYPE for the
// interface INTERFACE.
tree
Type
::
interface_method_table
(
Gogo
*
gogo
,
Type
*
type
,
const
Interface_type
*
interface
,
bool
is_pointer
,
Interface_method_tables
**
method_tables
,
Interface_method_tables
**
pointer_tables
)
{
go_assert
(
!
interface
->
is_empty
());
Interface_method_tables
**
pimt
=
is_pointer
?
method_tables
:
pointer_tables
;
if
(
*
pimt
==
NULL
)
*
pimt
=
new
Interface_method_tables
(
5
);
std
::
pair
<
const
Interface_type
*
,
tree
>
val
(
interface
,
NULL_TREE
);
std
::
pair
<
Interface_method_tables
::
iterator
,
bool
>
ins
=
(
*
pimt
)
->
insert
(
val
);
if
(
ins
.
second
)
{
// This is a new entry in the hash table.
go_assert
(
ins
.
first
->
second
==
NULL_TREE
);
ins
.
first
->
second
=
gogo
->
interface_method_table_for_type
(
interface
,
type
,
is_pointer
);
}
tree
decl
=
ins
.
first
->
second
;
if
(
decl
==
error_mark_node
)
return
error_mark_node
;
go_assert
(
decl
!=
NULL_TREE
&&
TREE_CODE
(
decl
)
==
VAR_DECL
);
return
build_fold_addr_expr
(
decl
);
}
// Look for field or method NAME for TYPE. Return an Expression for
// the field or method bound to EXPR. If there is no such field or
// method, give an appropriate error and return an error expression.
...
...
gcc/go/gofrontend/types.h
View file @
0efaba3c
...
...
@@ -983,6 +983,19 @@ class Type
method_function
(
const
Methods
*
,
const
std
::
string
&
name
,
bool
*
is_ambiguous
);
// 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
,
Type_identical
)
Interface_method_tables
;
// Return a pointer to the interface method table for TYPE for the
// interface INTERFACE.
static
tree
interface_method_table
(
Gogo
*
gogo
,
Type
*
type
,
const
Interface_type
*
interface
,
bool
is_pointer
,
Interface_method_tables
**
method_tables
,
Interface_method_tables
**
pointer_tables
);
// Return a composite literal for the type descriptor entry for a
// type.
static
Expression
*
...
...
@@ -1994,7 +2007,8 @@ class Struct_type : public Type
public
:
Struct_type
(
Struct_field_list
*
fields
,
Location
location
)
:
Type
(
TYPE_STRUCT
),
fields_
(
fields
),
location_
(
location
),
all_methods_
(
NULL
)
fields_
(
fields
),
location_
(
location
),
all_methods_
(
NULL
),
interface_method_tables_
(
NULL
),
pointer_interface_method_tables_
(
NULL
)
{
}
// Return the field NAME. This only looks at local fields, not at
...
...
@@ -2076,6 +2090,14 @@ class Struct_type : public Type
Method
*
method_function
(
const
std
::
string
&
name
,
bool
*
is_ambiguous
)
const
;
// Return a pointer to the interface method table for this type for
// the interface INTERFACE. If IS_POINTER is true, set the type
// descriptor to a pointer to this type, otherwise set it to this
// type.
tree
interface_method_table
(
Gogo
*
,
const
Interface_type
*
interface
,
bool
is_pointer
);
// Traverse just the field types of a struct type.
int
traverse_field_types
(
Traverse
*
traverse
)
...
...
@@ -2156,6 +2178,13 @@ class Struct_type : public Type
Location
location_
;
// If this struct is unnamed, a list of methods.
Methods
*
all_methods_
;
// A mapping from interfaces to the associated interface method
// tables for this type. Only used if this struct is unnamed.
Interface_method_tables
*
interface_method_tables_
;
// A mapping from interfaces to the associated interface method
// tables for pointers to this type. Only used if this struct is
// unnamed.
Interface_method_tables
*
pointer_interface_method_tables_
;
};
// The type of an array.
...
...
@@ -2861,11 +2890,6 @@ class Named_type : public Type
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
,
Type_identical
)
Interface_method_tables
;
// A pointer back to the Named_object for this type.
Named_object
*
named_object_
;
// If this type is defined in a function, a pointer back to the
...
...
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