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
f6338016
Commit
f6338016
authored
Nov 28, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Implement //go:nointerface comments.
From-SVN: r193874
parent
cfbeaedf
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
126 additions
and
7 deletions
+126
-7
gcc/go/gofrontend/gogo.cc
+2
-2
gcc/go/gofrontend/gogo.h
+20
-0
gcc/go/gofrontend/lex.cc
+8
-1
gcc/go/gofrontend/lex.h
+12
-0
gcc/go/gofrontend/parse.cc
+27
-3
gcc/go/gofrontend/parse.h
+1
-1
gcc/go/gofrontend/types.cc
+37
-0
gcc/go/gofrontend/types.h
+19
-0
No files found.
gcc/go/gofrontend/gogo.cc
View file @
f6338016
...
...
@@ -3074,8 +3074,8 @@ Function::Function(Function_type* type, Function* enclosing, Block* block,
:
type_
(
type
),
enclosing_
(
enclosing
),
results_
(
NULL
),
closure_var_
(
NULL
),
block_
(
block
),
location_
(
location
),
labels_
(),
local_type_count_
(
0
),
fndecl_
(
NULL
),
defer_stack_
(
NULL
),
results_are_named_
(
false
),
calls_recover_
(
false
),
is_recover_thunk
_
(
false
),
has_recover_thunk_
(
false
)
results_are_named_
(
false
),
nointerface_
(
false
),
calls_recover
_
(
false
),
is_recover_thunk_
(
false
),
has_recover_thunk_
(
false
)
{
}
...
...
gcc/go/gofrontend/gogo.h
View file @
f6338016
...
...
@@ -911,6 +911,24 @@ class Function
results_are_named
()
const
{
return
this
->
results_are_named_
;
}
// Whether this method should not be included in the type
// descriptor.
bool
nointerface
()
const
{
go_assert
(
this
->
is_method
());
return
this
->
nointerface_
;
}
// Record that this method should not be included in the type
// descriptor.
void
set_nointerface
()
{
go_assert
(
this
->
is_method
());
this
->
nointerface_
=
true
;
}
// Add a new field to the closure variable.
void
add_closure_field
(
Named_object
*
var
,
Location
loc
)
...
...
@@ -1113,6 +1131,8 @@ class Function
Temporary_statement
*
defer_stack_
;
// True if the result variables are named.
bool
results_are_named_
;
// True if this method should not be included in the type descriptor.
bool
nointerface_
;
// True if this function calls the predeclared recover function.
bool
calls_recover_
;
// True if this a thunk built for a function which calls recover.
...
...
gcc/go/gofrontend/lex.cc
View file @
f6338016
...
...
@@ -442,7 +442,8 @@ Token::print(FILE* file) const
Lex
::
Lex
(
const
char
*
input_file_name
,
FILE
*
input_file
,
Linemap
*
linemap
)
:
input_file_name_
(
input_file_name
),
input_file_
(
input_file
),
linemap_
(
linemap
),
linebuf_
(
NULL
),
linebufsize_
(
120
),
linesize_
(
0
),
lineoff_
(
0
),
lineno_
(
0
),
add_semi_at_eol_
(
false
),
extern_
()
lineoff_
(
0
),
lineno_
(
0
),
add_semi_at_eol_
(
false
),
saw_nointerface_
(
false
),
extern_
()
{
this
->
linebuf_
=
new
char
[
this
->
linebufsize_
];
this
->
linemap_
->
start_file
(
input_file_name
,
0
);
...
...
@@ -1704,6 +1705,12 @@ Lex::skip_cpp_comment()
this
->
extern_
=
std
::
string
(
p
,
plend
-
p
);
}
// For field tracking analysis: a //go:nointerface comment means
// that the next interface method should not be stored in the type
// descriptor. This permits it to be discarded if it is not needed.
if
(
this
->
lineoff_
==
2
&&
memcmp
(
p
,
"go:nointerface"
,
14
)
==
0
)
this
->
saw_nointerface_
=
true
;
while
(
p
<
pend
)
{
this
->
lineoff_
=
p
-
this
->
linebuf_
;
...
...
gcc/go/gofrontend/lex.h
View file @
f6338016
...
...
@@ -349,6 +349,16 @@ class Lex
extern_name
()
const
{
return
this
->
extern_
;
}
// Return whether we have seen a //go:nointerface comment, clearing
// the flag.
bool
get_and_clear_nointerface
()
{
bool
ret
=
this
->
saw_nointerface_
;
this
->
saw_nointerface_
=
false
;
return
ret
;
}
// Return whether the identifier NAME should be exported. NAME is a
// mangled name which includes only ASCII characters.
static
bool
...
...
@@ -483,6 +493,8 @@ class Lex
size_t
lineno_
;
// Whether to add a semicolon if we see a newline now.
bool
add_semi_at_eol_
;
// Whether we just saw a magic go:nointerface comment.
bool
saw_nointerface_
;
// The external name to use for a function declaration, from a magic
// //extern comment.
std
::
string
extern_
;
...
...
gcc/go/gofrontend/parse.cc
View file @
f6338016
...
...
@@ -1280,6 +1280,12 @@ void
Parse
::
declaration
()
{
const
Token
*
token
=
this
->
peek_token
();
bool
saw_nointerface
=
this
->
lex_
->
get_and_clear_nointerface
();
if
(
saw_nointerface
&&
!
token
->
is_keyword
(
KEYWORD_FUNC
))
warning_at
(
token
->
location
(),
0
,
"ignoring magic //go:nointerface comment before non-method"
);
if
(
token
->
is_keyword
(
KEYWORD_CONST
))
this
->
const_decl
();
else
if
(
token
->
is_keyword
(
KEYWORD_TYPE
))
...
...
@@ -1287,7 +1293,7 @@ Parse::declaration()
else
if
(
token
->
is_keyword
(
KEYWORD_VAR
))
this
->
var_decl
();
else
if
(
token
->
is_keyword
(
KEYWORD_FUNC
))
this
->
function_decl
();
this
->
function_decl
(
saw_nointerface
);
else
{
error_at
(
this
->
location
(),
"expected declaration"
);
...
...
@@ -2166,8 +2172,11 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
// inside the asm. This extension will be removed at some future
// date. It has been replaced with //extern comments.
// SAW_NOINTERFACE is true if we saw a magic //go:nointerface comment,
// which means that we omit the method from the type descriptor.
void
Parse
::
function_decl
()
Parse
::
function_decl
(
bool
saw_nointerface
)
{
go_assert
(
this
->
peek_token
()
->
is_keyword
(
KEYWORD_FUNC
));
Location
location
=
this
->
location
();
...
...
@@ -2180,6 +2189,12 @@ Parse::function_decl()
rec
=
this
->
receiver
();
token
=
this
->
peek_token
();
}
else
if
(
saw_nointerface
)
{
warning_at
(
location
,
0
,
"ignoring magic //go:nointerface comment before non-method"
);
saw_nointerface
=
false
;
}
if
(
!
token
->
is_identifier
())
{
...
...
@@ -2256,6 +2271,11 @@ Parse::function_decl()
}
}
}
if
(
saw_nointerface
)
warning_at
(
location
,
0
,
(
"ignoring magic //go:nointerface comment "
"before declaration"
));
}
else
{
...
...
@@ -2268,9 +2288,13 @@ Parse::function_decl()
this
->
gogo_
->
add_erroneous_name
(
name
);
name
=
this
->
gogo_
->
pack_hidden_name
(
"_"
,
false
);
}
this
->
gogo_
->
start_function
(
name
,
fntype
,
true
,
location
);
named_object
=
this
->
gogo_
->
start_function
(
name
,
fntype
,
true
,
location
);
Location
end_loc
=
this
->
block
();
this
->
gogo_
->
finish_function
(
end_loc
);
if
(
saw_nointerface
&&
!
this
->
is_erroneous_function_
&&
named_object
->
is_function
())
named_object
->
func_value
()
->
set_nointerface
();
this
->
is_erroneous_function_
=
hold_is_erroneous_function
;
}
}
...
...
gcc/go/gofrontend/parse.h
View file @
f6338016
...
...
@@ -214,7 +214,7 @@ class Parse
void
simple_var_decl_or_assignment
(
const
std
::
string
&
,
Location
,
bool
may_be_composite_lit
,
Range_clause
*
,
Type_switch
*
);
void
function_decl
();
void
function_decl
(
bool
saw_nointerface
);
Typed_identifier
*
receiver
();
Expression
*
operand
(
bool
may_be_sink
);
Expression
*
enclosing_var_reference
(
Named_object
*
,
Named_object
*
,
...
...
gcc/go/gofrontend/types.cc
View file @
f6338016
...
...
@@ -2068,6 +2068,13 @@ Type::methods_constructor(Gogo* gogo, Type* methods_type,
continue
;
if
(
only_value_methods
&&
!
p
->
second
->
is_value_method
())
continue
;
// This is where we implement the magic //go:nointerface
// comment. If we saw that comment, we don't add this
// method to the type descriptor.
if
(
p
->
second
->
nointerface
())
continue
;
smethods
.
push_back
(
std
::
make_pair
(
p
->
first
,
p
->
second
));
}
}
...
...
@@ -6891,6 +6898,24 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
}
return
false
;
}
// If the magic //go:nointerface comment was used, the method
// may not be used to implement interfaces.
if
(
m
->
nointerface
())
{
if
(
reason
!=
NULL
)
{
std
::
string
n
=
Gogo
::
message_name
(
p
->
name
());
size_t
len
=
100
+
n
.
length
();
char
*
buf
=
new
char
[
len
];
snprintf
(
buf
,
len
,
_
(
"method %s%s%s is marked go:nointerface"
),
open_quote
,
n
.
c_str
(),
close_quote
);
reason
->
assign
(
buf
);
delete
[]
buf
;
}
return
false
;
}
}
return
true
;
...
...
@@ -7530,6 +7555,15 @@ Named_method::do_bind_method(Expression* expr, Location location) const
return
bme
;
}
// Return whether this method should not participate in interfaces.
bool
Named_method
::
do_nointerface
()
const
{
Named_object
*
no
=
this
->
named_object_
;
return
no
->
is_function
()
&&
no
->
func_value
()
->
nointerface
();
}
// Class Interface_method.
// Bind a method to an object.
...
...
@@ -8834,6 +8868,9 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
Type
::
build_one_stub_method
(
gogo
,
m
,
buf
,
stub_params
,
fntype
->
is_varargs
(),
location
);
gogo
->
finish_function
(
fntype
->
location
());
if
(
m
->
nointerface
()
&&
stub
->
is_function
())
stub
->
func_value
()
->
set_nointerface
();
}
m
->
set_stub_object
(
stub
);
...
...
gcc/go/gofrontend/types.h
View file @
f6338016
...
...
@@ -179,6 +179,12 @@ class Method
this
->
stub_
=
no
;
}
// Return true if this method should not participate in any
// interfaces.
bool
nointerface
()
const
{
return
this
->
do_nointerface
();
}
protected
:
// These objects are only built by the child classes.
Method
(
const
Field_indexes
*
field_indexes
,
unsigned
int
depth
,
...
...
@@ -204,6 +210,10 @@ class Method
virtual
Expression
*
do_bind_method
(
Expression
*
expr
,
Location
location
)
const
=
0
;
// Return whether this method should not participate in interfaces.
virtual
bool
do_nointerface
()
const
=
0
;
private
:
// The sequence of field indexes used for this method. If this is
// NULL, then the method is defined for the current type.
...
...
@@ -254,6 +264,10 @@ class Named_method : public Method
Expression
*
do_bind_method
(
Expression
*
expr
,
Location
location
)
const
;
// Return whether this method should not participate in interfaces.
bool
do_nointerface
()
const
;
private
:
// The method itself. For a method which needs a stub, this starts
// out as the underlying method, and is later replaced with the stub
...
...
@@ -295,6 +309,11 @@ class Interface_method : public Method
Expression
*
do_bind_method
(
Expression
*
expr
,
Location
location
)
const
;
// Return whether this method should not participate in interfaces.
bool
do_nointerface
()
const
{
return
false
;
}
private
:
// The name of the interface method to call.
std
::
string
name_
;
...
...
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