aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
committerAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
commitb9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch)
treeed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/go
parent1957047ed1c94bf17cf993a2b1866965f493ba87 (diff)
parent56638b9b1853666f575928f8baf17f70e4ed3517 (diff)
downloadgcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517 Author: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed Jun 17 00:16:36 2020 +0000 Daily bump.
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/ChangeLog9
-rw-r--r--gcc/go/go-gcc.cc179
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/export.cc2
-rw-r--r--gcc/go/gofrontend/expressions.cc193
-rw-r--r--gcc/go/gofrontend/expressions.h22
-rw-r--r--gcc/go/gofrontend/gogo.h4
-rw-r--r--gcc/go/gofrontend/lex.cc12
-rw-r--r--gcc/go/gofrontend/names.cc2
-rw-r--r--gcc/go/gofrontend/parse.cc25
-rw-r--r--gcc/go/gofrontend/parse.h2
-rw-r--r--gcc/go/gofrontend/types.cc26
12 files changed, 287 insertions, 191 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index fc73347..5be05e9 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,12 @@
+2020-04-15 Ian Lance Taylor <iant@golang.org>
+
+ PR go/94607
+ * go-gcc.cc (class Gcc_backend): Define builtin_const,
+ builtin_noreturn, builtin_novops.
+ (Gcc_backend::define_builtin): Change const_p and noreturn_p
+ parameters to a single flags parameter. Change all callers.
+ (Gcc_backend::Gcc_backend): Pass novops for prefetch.
+
2020-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 0960894..fd96481 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -541,9 +541,13 @@ class Gcc_backend : public Backend
convert_tree(tree, tree, Location);
private:
+ static const int builtin_const = 1 << 0;
+ static const int builtin_noreturn = 1 << 1;
+ static const int builtin_novops = 1 << 2;
+
void
define_builtin(built_in_function bcode, const char* name, const char* libname,
- tree fntype, bool const_p, bool noreturn_p);
+ tree fntype, int flags);
// A mapping of the GCC built-ins exposed to GCCGo.
std::map<std::string, Bfunction*> builtin_functions_;
@@ -566,26 +570,22 @@ Gcc_backend::Gcc_backend()
tree t = this->integer_type(true, BITS_PER_UNIT)->get_tree();
tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
- NULL, build_function_type_list(t, p, t, NULL_TREE),
- false, false);
+ NULL, build_function_type_list(t, p, t, NULL_TREE), 0);
t = this->integer_type(true, BITS_PER_UNIT * 2)->get_tree();
p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
- NULL, build_function_type_list(t, p, t, NULL_TREE),
- false, false);
+ NULL, build_function_type_list(t, p, t, NULL_TREE), 0);
t = this->integer_type(true, BITS_PER_UNIT * 4)->get_tree();
p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
- NULL, build_function_type_list(t, p, t, NULL_TREE),
- false, false);
+ NULL, build_function_type_list(t, p, t, NULL_TREE), 0);
t = this->integer_type(true, BITS_PER_UNIT * 8)->get_tree();
p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
- NULL, build_function_type_list(t, p, t, NULL_TREE),
- false, false);
+ NULL, build_function_type_list(t, p, t, NULL_TREE), 0);
// We use __builtin_expect for magic import functions.
this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
@@ -593,7 +593,7 @@ Gcc_backend::Gcc_backend()
long_integer_type_node,
long_integer_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
// We use __builtin_memcmp for struct comparisons.
this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
@@ -602,7 +602,7 @@ Gcc_backend::Gcc_backend()
const_ptr_type_node,
size_type_node,
NULL_TREE),
- false, false);
+ 0);
// We use __builtin_memmove for copying data.
this->define_builtin(BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
@@ -611,7 +611,7 @@ Gcc_backend::Gcc_backend()
const_ptr_type_node,
size_type_node,
NULL_TREE),
- false, false);
+ 0);
// We use __builtin_memset for zeroing data.
this->define_builtin(BUILT_IN_MEMSET, "__builtin_memset", "memset",
@@ -620,54 +620,54 @@ Gcc_backend::Gcc_backend()
integer_type_node,
size_type_node,
NULL_TREE),
- false, false);
+ 0);
// Used by runtime/internal/sys and math/bits.
this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz",
build_function_type_list(integer_type_node,
unsigned_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
build_function_type_list(integer_type_node,
long_long_unsigned_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_CLZ, "__builtin_clz", "clz",
build_function_type_list(integer_type_node,
unsigned_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
build_function_type_list(integer_type_node,
long_long_unsigned_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
build_function_type_list(integer_type_node,
unsigned_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_POPCOUNTLL, "__builtin_popcountll", "popcountll",
build_function_type_list(integer_type_node,
long_long_unsigned_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
build_function_type_list(uint16_type_node,
uint16_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
build_function_type_list(uint32_type_node,
uint32_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
build_function_type_list(uint64_type_node,
uint64_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
// We provide some functions for the math library.
tree math_function_type = build_function_type_list(double_type_node,
@@ -684,104 +684,104 @@ Gcc_backend::Gcc_backend()
build_function_type_list(long_double_type_node, long_double_type_node,
long_double_type_node, NULL_TREE);
this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
- math_function_type_two, true, false);
+ math_function_type_two, builtin_const);
this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
- math_function_type_long_two, true, false);
+ math_function_type_long_two, builtin_const);
this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
- math_function_type_two, true, false);
+ math_function_type_two, builtin_const);
this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
- math_function_type_long_two, true, false);
+ math_function_type_long_two, builtin_const);
this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
build_function_type_list(double_type_node,
double_type_node,
integer_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
build_function_type_list(long_double_type_node,
long_double_type_node,
integer_type_node,
NULL_TREE),
- true, false);
+ builtin_const);
this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
- math_function_type, true, false);
+ math_function_type, builtin_const);
this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
- math_function_type_long, true, false);
+ math_function_type_long, builtin_const);
// We use __builtin_return_address in the thunk we build for
// functions which call recover, and for runtime.getcallerpc.
t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE);
this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
- NULL, t, false, false);
+ NULL, t, 0);
// The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
t = build_function_type_list(ptr_type_node, NULL_TREE);
this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa",
- NULL, t, false, false);
+ NULL, t, 0);
// The runtime calls __builtin_extract_return_addr when recording
// the address to which a function returns.
@@ -790,26 +790,26 @@ Gcc_backend::Gcc_backend()
build_function_type_list(ptr_type_node,
ptr_type_node,
NULL_TREE),
- false, false);
+ 0);
// The compiler uses __builtin_trap for some exception handling
// cases.
this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
build_function_type(void_type_node, void_list_node),
- false, true);
+ builtin_noreturn);
// The runtime uses __builtin_prefetch.
this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
build_varargs_function_type_list(void_type_node,
const_ptr_type_node,
NULL_TREE),
- false, false);
+ builtin_novops);
// The compiler uses __builtin_unreachable for cases that cannot
// occur.
this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
build_function_type(void_type_node, void_list_node),
- true, true);
+ builtin_const | builtin_noreturn);
// We provide some atomic functions.
t = build_function_type_list(uint32_type_node,
@@ -817,14 +817,14 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(uint64_type_node,
ptr_type_node,
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(void_type_node,
ptr_type_node,
@@ -832,7 +832,7 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(void_type_node,
ptr_type_node,
@@ -840,7 +840,7 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(uint32_type_node,
ptr_type_node,
@@ -848,7 +848,7 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(uint64_type_node,
ptr_type_node,
@@ -856,7 +856,7 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(boolean_type_node,
ptr_type_node,
@@ -868,7 +868,7 @@ Gcc_backend::Gcc_backend()
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
"__atomic_compare_exchange_4", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(boolean_type_node,
ptr_type_node,
@@ -880,7 +880,7 @@ Gcc_backend::Gcc_backend()
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
"__atomic_compare_exchange_8", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(uint32_type_node,
ptr_type_node,
@@ -888,7 +888,7 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(uint64_type_node,
ptr_type_node,
@@ -896,7 +896,7 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(unsigned_char_type_node,
ptr_type_node,
@@ -904,9 +904,9 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", NULL,
- t, false, false);
+ t, 0);
this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", NULL,
- t, false, false);
+ t, 0);
t = build_function_type_list(unsigned_char_type_node,
ptr_type_node,
@@ -914,9 +914,9 @@ Gcc_backend::Gcc_backend()
integer_type_node,
NULL_TREE);
this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
- t, false, false);
+ t, 0);
this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
- t, false, false);
+ t, 0);
}
// Get an unnamed integer type.
@@ -3482,25 +3482,28 @@ Gcc_backend::write_export_data(const char* bytes, unsigned int size)
void
Gcc_backend::define_builtin(built_in_function bcode, const char* name,
- const char* libname, tree fntype, bool const_p,
- bool noreturn_p)
+ const char* libname, tree fntype, int flags)
{
tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
libname, NULL_TREE);
- if (const_p)
+ if ((flags & builtin_const) != 0)
TREE_READONLY(decl) = 1;
- if (noreturn_p)
+ if ((flags & builtin_noreturn) != 0)
TREE_THIS_VOLATILE(decl) = 1;
+ if ((flags & builtin_novops) != 0)
+ DECL_IS_NOVOPS(decl) = 1;
set_builtin_decl(bcode, decl, true);
this->builtin_functions_[name] = this->make_function(decl);
if (libname != NULL)
{
decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
NULL, NULL_TREE);
- if (const_p)
+ if ((flags & builtin_const) != 0)
TREE_READONLY(decl) = 1;
- if (noreturn_p)
+ if ((flags & builtin_noreturn) != 0)
TREE_THIS_VOLATILE(decl) = 1;
+ if ((flags & builtin_novops) != 0)
+ DECL_IS_NOVOPS(decl) = 1;
this->builtin_functions_[libname] = this->make_function(decl);
}
}
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d993dc8..fa37648 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-e0790a756e9ba77e2d3d6ef5d0abbb11dd71211b
+d4dade353648eae4a1eaa1acd3e4ce1f7180a913
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc
index b27d2fa..277aa74 100644
--- a/gcc/go/gofrontend/export.cc
+++ b/gcc/go/gofrontend/export.cc
@@ -1231,7 +1231,7 @@ Export::write_name(const std::string& name)
if (name.empty())
this->write_c_string("?");
else
- this->write_string(Gogo::message_name(name));
+ this->write_string(Gogo::unpack_hidden_name(name));
}
// Write an integer value to the export stream.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index af09138..deac874 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -1761,8 +1761,6 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
real = no->unknown_value()->real_named_object();
if (real == NULL)
{
- if (this->is_composite_literal_key_)
- return this;
if (!this->no_error_message_)
go_error_at(location, "reference to undefined name %qs",
this->named_object_->message_name().c_str());
@@ -1776,8 +1774,6 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
case Named_object::NAMED_OBJECT_TYPE:
return Expression::make_type(real->type_value(), location);
case Named_object::NAMED_OBJECT_TYPE_DECLARATION:
- if (this->is_composite_literal_key_)
- return this;
if (!this->no_error_message_)
go_error_at(location, "reference to undefined type %qs",
real->message_name().c_str());
@@ -1789,8 +1785,6 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
return Expression::make_func_reference(real, NULL, location);
case Named_object::NAMED_OBJECT_PACKAGE:
- if (this->is_composite_literal_key_)
- return this;
if (!this->no_error_message_)
go_error_at(location, "unexpected reference to package");
return Expression::make_error(location);
@@ -2586,11 +2580,11 @@ Integer_expression::do_import(Import_expression* imp, Location loc)
return Expression::make_error(loc);
}
if (pos == std::string::npos)
- mpfr_set_ui(real, 0, GMP_RNDN);
+ mpfr_set_ui(real, 0, MPFR_RNDN);
else
{
std::string real_str = num.substr(0, pos);
- if (mpfr_init_set_str(real, real_str.c_str(), 10, GMP_RNDN) != 0)
+ if (mpfr_init_set_str(real, real_str.c_str(), 10, MPFR_RNDN) != 0)
{
go_error_at(imp->location(), "bad number in import data: %qs",
real_str.c_str());
@@ -2605,7 +2599,7 @@ Integer_expression::do_import(Import_expression* imp, Location loc)
imag_str = num.substr(pos);
imag_str = imag_str.substr(0, imag_str.size() - 1);
mpfr_t imag;
- if (mpfr_init_set_str(imag, imag_str.c_str(), 10, GMP_RNDN) != 0)
+ if (mpfr_init_set_str(imag, imag_str.c_str(), 10, MPFR_RNDN) != 0)
{
go_error_at(imp->location(), "bad number in import data: %qs",
imag_str.c_str());
@@ -2645,7 +2639,7 @@ Integer_expression::do_import(Import_expression* imp, Location loc)
else
{
mpfr_t val;
- if (mpfr_init_set_str(val, num.c_str(), 10, GMP_RNDN) != 0)
+ if (mpfr_init_set_str(val, num.c_str(), 10, MPFR_RNDN) != 0)
{
go_error_at(imp->location(), "bad number in import data: %qs",
num.c_str());
@@ -2759,7 +2753,7 @@ class Float_expression : public Expression
: Expression(EXPRESSION_FLOAT, location),
type_(type)
{
- mpfr_init_set(this->val_, *val, GMP_RNDN);
+ mpfr_init_set(this->val_, *val, MPFR_RNDN);
}
// Write VAL to export data.
@@ -2929,8 +2923,8 @@ Float_expression::do_get_backend(Translate_context* context)
void
Float_expression::export_float(String_dump *exp, const mpfr_t val)
{
- mp_exp_t exponent;
- char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
+ mpfr_exp_t exponent;
+ char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, MPFR_RNDN);
if (*s == '-')
exp->write_c_string("-");
exp->write_c_string("0.");
@@ -4787,7 +4781,7 @@ Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
unc->get_float(&uval);
mpfr_t val;
mpfr_init(val);
- mpfr_neg(val, uval, GMP_RNDN);
+ mpfr_neg(val, uval, MPFR_RNDN);
nc->set_float(unc->type(), val);
mpfr_clear(uval);
mpfr_clear(val);
@@ -5619,8 +5613,8 @@ Binary_expression::compare_float(const Numeric_constant* left_nc,
if (!type->is_abstract() && type->float_type() != NULL)
{
int bits = type->float_type()->bits();
- mpfr_prec_round(left_val, bits, GMP_RNDN);
- mpfr_prec_round(right_val, bits, GMP_RNDN);
+ mpfr_prec_round(left_val, bits, MPFR_RNDN);
+ mpfr_prec_round(right_val, bits, MPFR_RNDN);
}
*cmp = mpfr_cmp(left_val, right_val);
@@ -5655,10 +5649,10 @@ Binary_expression::compare_complex(const Numeric_constant* left_nc,
if (!type->is_abstract() && type->complex_type() != NULL)
{
int bits = type->complex_type()->bits();
- mpfr_prec_round(mpc_realref(left_val), bits / 2, GMP_RNDN);
- mpfr_prec_round(mpc_imagref(left_val), bits / 2, GMP_RNDN);
- mpfr_prec_round(mpc_realref(right_val), bits / 2, GMP_RNDN);
- mpfr_prec_round(mpc_imagref(right_val), bits / 2, GMP_RNDN);
+ mpfr_prec_round(mpc_realref(left_val), bits / 2, MPFR_RNDN);
+ mpfr_prec_round(mpc_imagref(left_val), bits / 2, MPFR_RNDN);
+ mpfr_prec_round(mpc_realref(right_val), bits / 2, MPFR_RNDN);
+ mpfr_prec_round(mpc_imagref(right_val), bits / 2, MPFR_RNDN);
}
*cmp = mpc_cmp(left_val, right_val) != 0;
@@ -5905,10 +5899,10 @@ Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
switch (op)
{
case OPERATOR_PLUS:
- mpfr_add(val, left_val, right_val, GMP_RNDN);
+ mpfr_add(val, left_val, right_val, MPFR_RNDN);
break;
case OPERATOR_MINUS:
- mpfr_sub(val, left_val, right_val, GMP_RNDN);
+ mpfr_sub(val, left_val, right_val, MPFR_RNDN);
break;
case OPERATOR_OR:
case OPERATOR_XOR:
@@ -5917,20 +5911,20 @@ Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
case OPERATOR_MOD:
case OPERATOR_LSHIFT:
case OPERATOR_RSHIFT:
- mpfr_set_ui(val, 0, GMP_RNDN);
+ mpfr_set_ui(val, 0, MPFR_RNDN);
ret = false;
break;
case OPERATOR_MULT:
- mpfr_mul(val, left_val, right_val, GMP_RNDN);
+ mpfr_mul(val, left_val, right_val, MPFR_RNDN);
break;
case OPERATOR_DIV:
if (!mpfr_zero_p(right_val))
- mpfr_div(val, left_val, right_val, GMP_RNDN);
+ mpfr_div(val, left_val, right_val, MPFR_RNDN);
else
{
go_error_at(location, "division by zero");
nc->set_invalid();
- mpfr_set_ui(val, 0, GMP_RNDN);
+ mpfr_set_ui(val, 0, MPFR_RNDN);
}
break;
default:
@@ -15992,6 +15986,85 @@ Map_construction_expression::do_dump_expression(
ast_dump_context->ostream() << "}";
}
+// A composite literal key. This is seen during parsing, but is not
+// resolved to a named_object in case this is a composite literal of
+// struct type.
+
+class Composite_literal_key_expression : public Parser_expression
+{
+ public:
+ Composite_literal_key_expression(const std::string& name, Location location)
+ : Parser_expression(EXPRESSION_COMPOSITE_LITERAL_KEY, location),
+ name_(name)
+ { }
+
+ const std::string&
+ name() const
+ { return this->name_; }
+
+ protected:
+ Expression*
+ do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+
+ Expression*
+ do_copy()
+ {
+ return new Composite_literal_key_expression(this->name_, this->location());
+ }
+
+ void
+ do_dump_expression(Ast_dump_context*) const;
+
+ private:
+ // The name.
+ std::string name_;
+};
+
+// Lower a composite literal key. We will never get here for keys in
+// composite literals of struct types, because that is prevented by
+// Composite_literal_expression::do_traverse. So if we do get here,
+// this must be a regular name reference after all.
+
+Expression*
+Composite_literal_key_expression::do_lower(Gogo* gogo, Named_object*,
+ Statement_inserter*, int)
+{
+ Named_object* no = gogo->lookup(this->name_, NULL);
+ if (no == NULL)
+ {
+ // Gogo::lookup doesn't look in the global namespace, and names
+ // used in composite literal keys aren't seen by
+ // Gogo::define_global_names, so we have to look in the global
+ // namespace ourselves.
+ no = gogo->lookup_global(Gogo::unpack_hidden_name(this->name_).c_str());
+ if (no == NULL)
+ {
+ go_error_at(this->location(), "reference to undefined name %qs",
+ Gogo::message_name(this->name_).c_str());
+ return Expression::make_error(this->location());
+ }
+ }
+ return Expression::make_unknown_reference(no, this->location());
+}
+
+// Dump a composite literal key.
+
+void
+Composite_literal_key_expression::do_dump_expression(
+ Ast_dump_context* ast_dump_context) const
+{
+ ast_dump_context->ostream() << "_UnknownName_(" << this->name_ << ")";
+}
+
+// Make a composite literal key.
+
+Expression*
+Expression::make_composite_literal_key(const std::string& name,
+ Location location)
+{
+ return new Composite_literal_key_expression(name, location);
+}
+
// Class Composite_literal_expression.
// Traversal.
@@ -16013,6 +16086,7 @@ Composite_literal_expression::do_traverse(Traverse* traverse)
for (int depth = 0; depth < this->depth_; ++depth)
{
+ type = type->deref();
if (type->array_type() != NULL)
type = type->array_type()->element_type();
else if (type->map_type() != NULL)
@@ -16028,6 +16102,7 @@ Composite_literal_expression::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE;
}
}
+ type = type->deref();
while (true)
{
@@ -16186,6 +16261,11 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
const Named_object* no = NULL;
switch (name_expr->classification())
{
+ case EXPRESSION_COMPOSITE_LITERAL_KEY:
+ name =
+ static_cast<Composite_literal_key_expression*>(name_expr)->name();
+ break;
+
case EXPRESSION_UNKNOWN_REFERENCE:
name = name_expr->unknown_expression()->name();
if (type->named_type() != NULL)
@@ -16593,7 +16673,6 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
// literals. Lower it now to get the right error message.
if ((*p)->unknown_expression() != NULL)
{
- (*p)->unknown_expression()->clear_is_composite_literal_key();
gogo->lower_expression(function, inserter, &*p);
go_assert((*p)->is_error_expression());
return Expression::make_error(location);
@@ -18797,7 +18876,7 @@ Numeric_constant::Numeric_constant(const Numeric_constant& a)
mpz_init_set(this->u_.int_val, a.u_.int_val);
break;
case NC_FLOAT:
- mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
+ mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
break;
case NC_COMPLEX:
mpc_init2(this->u_.complex_val, mpc_precision);
@@ -18825,7 +18904,7 @@ Numeric_constant::operator=(const Numeric_constant& a)
mpz_init_set(this->u_.int_val, a.u_.int_val);
break;
case NC_FLOAT:
- mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
+ mpfr_init_set(this->u_.float_val, a.u_.float_val, MPFR_RNDN);
break;
case NC_COMPLEX:
mpc_init2(this->u_.complex_val, mpc_precision);
@@ -18943,9 +19022,9 @@ Numeric_constant::set_float(Type* type, const mpfr_t val)
&& !type->float_type()->is_abstract())
bits = type->float_type()->bits();
if (Numeric_constant::is_float_neg_zero(val, bits))
- mpfr_init_set_ui(this->u_.float_val, 0, GMP_RNDN);
+ mpfr_init_set_ui(this->u_.float_val, 0, MPFR_RNDN);
else
- mpfr_init_set(this->u_.float_val, val, GMP_RNDN);
+ mpfr_init_set(this->u_.float_val, val, MPFR_RNDN);
}
// Set to a complex value.
@@ -18965,14 +19044,14 @@ Numeric_constant::set_complex(Type* type, const mpc_t val)
bits = type->complex_type()->bits() / 2;
mpfr_t real;
- mpfr_init_set(real, mpc_realref(val), GMP_RNDN);
+ mpfr_init_set(real, mpc_realref(val), MPFR_RNDN);
if (Numeric_constant::is_float_neg_zero(real, bits))
- mpfr_set_ui(real, 0, GMP_RNDN);
+ mpfr_set_ui(real, 0, MPFR_RNDN);
mpfr_t imag;
- mpfr_init_set(imag, mpc_imagref(val), GMP_RNDN);
+ mpfr_init_set(imag, mpc_imagref(val), MPFR_RNDN);
if (Numeric_constant::is_float_neg_zero(imag, bits))
- mpfr_set_ui(imag, 0, GMP_RNDN);
+ mpfr_set_ui(imag, 0, MPFR_RNDN);
mpc_init2(this->u_.complex_val, mpc_precision);
mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
@@ -18991,7 +19070,7 @@ Numeric_constant::is_float_neg_zero(const mpfr_t val, int bits)
return false;
if (mpfr_zero_p(val))
return true;
- mp_exp_t min_exp;
+ mpfr_exp_t min_exp;
switch (bits)
{
case 0:
@@ -19036,7 +19115,7 @@ void
Numeric_constant::get_float(mpfr_t* val) const
{
go_assert(this->is_float());
- mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
+ mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
}
// Get a complex value.
@@ -19096,7 +19175,7 @@ Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
return NC_UL_NOTINT;
mpz_t ival;
mpz_init(ival);
- mpfr_get_z(ival, fval, GMP_RNDN);
+ mpfr_get_z(ival, fval, MPFR_RNDN);
To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
mpz_clear(ival);
return ret;
@@ -19163,7 +19242,7 @@ Numeric_constant::mpfr_to_memory_size(const mpfr_t fval, int64_t* val) const
return false;
mpz_t ival;
mpz_init(ival);
- mpfr_get_z(ival, fval, GMP_RNDN);
+ mpfr_get_z(ival, fval, MPFR_RNDN);
bool ret = this->mpz_to_memory_size(ival, val);
mpz_clear(ival);
return ret;
@@ -19184,14 +19263,14 @@ Numeric_constant::to_int(mpz_t* val) const
if (!mpfr_integer_p(this->u_.float_val))
return false;
mpz_init(*val);
- mpfr_get_z(*val, this->u_.float_val, GMP_RNDN);
+ mpfr_get_z(*val, this->u_.float_val, MPFR_RNDN);
return true;
case NC_COMPLEX:
if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val))
|| !mpfr_integer_p(mpc_realref(this->u_.complex_val)))
return false;
mpz_init(*val);
- mpfr_get_z(*val, mpc_realref(this->u_.complex_val), GMP_RNDN);
+ mpfr_get_z(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
return true;
default:
go_unreachable();
@@ -19207,15 +19286,15 @@ Numeric_constant::to_float(mpfr_t* val) const
{
case NC_INT:
case NC_RUNE:
- mpfr_init_set_z(*val, this->u_.int_val, GMP_RNDN);
+ mpfr_init_set_z(*val, this->u_.int_val, MPFR_RNDN);
return true;
case NC_FLOAT:
- mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
+ mpfr_init_set(*val, this->u_.float_val, MPFR_RNDN);
return true;
case NC_COMPLEX:
if (!mpfr_zero_p(mpc_imagref(this->u_.complex_val)))
return false;
- mpfr_init_set(*val, mpc_realref(this->u_.complex_val), GMP_RNDN);
+ mpfr_init_set(*val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
return true;
default:
go_unreachable();
@@ -19320,7 +19399,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
return false;
}
mpz_init(val);
- mpfr_get_z(val, this->u_.float_val, GMP_RNDN);
+ mpfr_get_z(val, this->u_.float_val, MPFR_RNDN);
break;
case NC_COMPLEX:
@@ -19335,7 +19414,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
return false;
}
mpz_init(val);
- mpfr_get_z(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
+ mpfr_get_z(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
break;
default:
@@ -19389,11 +19468,11 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
{
case NC_INT:
case NC_RUNE:
- mpfr_init_set_z(val, this->u_.int_val, GMP_RNDN);
+ mpfr_init_set_z(val, this->u_.int_val, MPFR_RNDN);
break;
case NC_FLOAT:
- mpfr_init_set(val, this->u_.float_val, GMP_RNDN);
+ mpfr_init_set(val, this->u_.float_val, MPFR_RNDN);
break;
case NC_COMPLEX:
@@ -19407,7 +19486,7 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
}
return false;
}
- mpfr_init_set(val, mpc_realref(this->u_.complex_val), GMP_RNDN);
+ mpfr_init_set(val, mpc_realref(this->u_.complex_val), MPFR_RNDN);
break;
default:
@@ -19424,8 +19503,8 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
}
else
{
- mp_exp_t exp = mpfr_get_exp(val);
- mp_exp_t max_exp;
+ mpfr_exp_t exp = mpfr_get_exp(val);
+ mpfr_exp_t max_exp;
switch (type->bits())
{
case 32:
@@ -19456,8 +19535,8 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
default:
go_unreachable();
}
- mpfr_set(t, val, GMP_RNDN);
- mpfr_set(val, t, GMP_RNDN);
+ mpfr_set(t, val, MPFR_RNDN);
+ mpfr_set(val, t, MPFR_RNDN);
mpfr_clear(t);
this->set_float(type, val);
@@ -19484,7 +19563,7 @@ Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
if (type->is_abstract())
return true;
- mp_exp_t max_exp;
+ mpfr_exp_t max_exp;
switch (type->bits())
{
case 64:
@@ -19616,12 +19695,12 @@ Numeric_constant::hash(unsigned int seed) const
break;
case NC_COMPLEX:
mpfr_init(m);
- mpc_abs(m, this->u_.complex_val, GMP_RNDN);
- val = mpfr_get_ui(m, GMP_RNDN);
+ mpc_abs(m, this->u_.complex_val, MPFR_RNDN);
+ val = mpfr_get_ui(m, MPFR_RNDN);
mpfr_clear(m);
break;
case NC_FLOAT:
- f = mpfr_get_d_2exp(&e, this->u_.float_val, GMP_RNDN) * 4294967295.0;
+ f = mpfr_get_d_2exp(&e, this->u_.float_val, MPFR_RNDN) * 4294967295.0;
val = static_cast<unsigned long>(e + static_cast<long>(f));
break;
default:
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index a0370e1..a4f892ac 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -127,6 +127,7 @@ class Expression
EXPRESSION_SLICE_CONSTRUCTION,
EXPRESSION_MAP_CONSTRUCTION,
EXPRESSION_COMPOSITE_LITERAL,
+ EXPRESSION_COMPOSITE_LITERAL_KEY,
EXPRESSION_HEAP,
EXPRESSION_RECEIVE,
EXPRESSION_TYPE_DESCRIPTOR,
@@ -384,6 +385,10 @@ class Expression
make_composite_literal(Type*, int depth, bool has_keys, Expression_list*,
bool all_are_names, Location);
+ // Make a composite literal key.
+ static Expression*
+ make_composite_literal_key(const std::string& name, Location);
+
// Make a struct composite literal.
static Expression*
make_struct_composite_literal(Type*, Expression_list*, Location);
@@ -2881,8 +2886,7 @@ class Unknown_expression : public Parser_expression
public:
Unknown_expression(Named_object* named_object, Location location)
: Parser_expression(EXPRESSION_UNKNOWN_REFERENCE, location),
- named_object_(named_object), no_error_message_(false),
- is_composite_literal_key_(false)
+ named_object_(named_object), no_error_message_(false)
{ }
// The associated named object.
@@ -2901,18 +2905,6 @@ class Unknown_expression : public Parser_expression
set_no_error_message()
{ this->no_error_message_ = true; }
- // Note that this expression is being used as the key in a composite
- // literal, so it may be OK if it is not resolved.
- void
- set_is_composite_literal_key()
- { this->is_composite_literal_key_ = true; }
-
- // Note that this expression should no longer be treated as a
- // composite literal key.
- void
- clear_is_composite_literal_key()
- { this->is_composite_literal_key_ = false; }
-
protected:
Expression*
do_lower(Gogo*, Named_object*, Statement_inserter*, int);
@@ -2930,8 +2922,6 @@ class Unknown_expression : public Parser_expression
// True if we should not give errors if this is undefined. This is
// used if there was a parse failure.
bool no_error_message_;
- // True if this is the key in a composite literal.
- bool is_composite_literal_key_;
};
// An index expression. This is lowered to an array index, a string
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 7d83119..2fb8a3a 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -958,7 +958,7 @@ class Gogo
// Return the name of the type descriptor list symbol of a package.
std::string
- type_descriptor_list_symbol(std::string);
+ type_descriptor_list_symbol(const std::string&);
// Return the name of the list of all type descriptor lists.
std::string
@@ -1073,7 +1073,7 @@ class Gogo
Specific_type_function(Type* atype, Named_type* aname, int64_t asize,
Specific_type_function_kind akind,
- const std::string afnname,
+ const std::string& afnname,
Function_type* afntype)
: type(atype), name(aname), size(asize), kind(akind),
fnname(afnname), fntype(afntype)
diff --git a/gcc/go/gofrontend/lex.cc b/gcc/go/gofrontend/lex.cc
index f023613..156a90c 100644
--- a/gcc/go/gofrontend/lex.cc
+++ b/gcc/go/gofrontend/lex.cc
@@ -198,7 +198,7 @@ Token::Token(const Token& tok)
break;
case TOKEN_FLOAT:
case TOKEN_IMAGINARY:
- mpfr_init_set(this->u_.float_value, tok.u_.float_value, GMP_RNDN);
+ mpfr_init_set(this->u_.float_value, tok.u_.float_value, MPFR_RNDN);
break;
default:
go_unreachable();
@@ -238,7 +238,7 @@ Token::operator=(const Token& tok)
break;
case TOKEN_FLOAT:
case TOKEN_IMAGINARY:
- mpfr_init_set(this->u_.float_value, tok.u_.float_value, GMP_RNDN);
+ mpfr_init_set(this->u_.float_value, tok.u_.float_value, MPFR_RNDN);
break;
default:
go_unreachable();
@@ -278,11 +278,11 @@ Token::print(FILE* file) const
break;
case TOKEN_FLOAT:
fprintf(file, "float ");
- mpfr_out_str(file, 10, 0, this->u_.float_value, GMP_RNDN);
+ mpfr_out_str(file, 10, 0, this->u_.float_value, MPFR_RNDN);
break;
case TOKEN_IMAGINARY:
fprintf(file, "imaginary ");
- mpfr_out_str(file, 10, 0, this->u_.float_value, GMP_RNDN);
+ mpfr_out_str(file, 10, 0, this->u_.float_value, MPFR_RNDN);
break;
case TOKEN_OPERATOR:
fprintf(file, "operator ");
@@ -1213,7 +1213,7 @@ Lex::gather_number()
else
{
mpfr_t ival;
- mpfr_init_set_z(ival, val, GMP_RNDN);
+ mpfr_init_set_z(ival, val, MPFR_RNDN);
mpz_clear(val);
Token ret = Token::make_imaginary_token(ival, location);
mpfr_clear(ival);
@@ -1310,7 +1310,7 @@ Lex::gather_number()
}
mpfr_t val;
- int r = mpfr_init_set_str(val, num.c_str(), base, GMP_RNDN);
+ int r = mpfr_init_set_str(val, num.c_str(), base, MPFR_RNDN);
go_assert(r == 0);
bool is_imaginary = *p == 'i';
diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc
index f4ad1815..a721a36 100644
--- a/gcc/go/gofrontend/names.cc
+++ b/gcc/go/gofrontend/names.cc
@@ -1024,7 +1024,7 @@ Gogo::type_descriptor_name(const Type* type, Named_type* nt)
// Return the name of the type descriptor list symbol of a package.
std::string
-Gogo::type_descriptor_list_symbol(std::string pkgpath)
+Gogo::type_descriptor_list_symbol(const std::string& pkgpath)
{
return pkgpath + "..types";
}
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index e50af61..ef59415 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -2200,7 +2200,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
p != til.end();
++p)
exprs->push_back(this->id_to_expression(p->name(), p->location(),
- true));
+ true, false));
Expression_list* more_exprs =
this->expression_list(NULL, true, may_be_composite_lit);
@@ -2651,7 +2651,7 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
case Token::TOKEN_IMAGINARY:
{
mpfr_t zero;
- mpfr_init_set_ui(zero, 0, GMP_RNDN);
+ mpfr_init_set_ui(zero, 0, MPFR_RNDN);
mpc_t val;
mpc_init2(val, mpc_precision);
mpc_set_fr_fr(val, zero, *token->imaginary_value(), MPC_RNDNN);
@@ -2820,7 +2820,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
Gogo* gogo = this->gogo_;
val = this->id_to_expression(gogo->pack_hidden_name(identifier,
is_exported),
- id_location, false);
+ id_location, false, true);
is_name = true;
}
else
@@ -2877,9 +2877,6 @@ Parse::composite_lit(Type* type, int depth, Location location)
}
has_keys = true;
- if (val->unknown_expression() != NULL)
- val->unknown_expression()->set_is_composite_literal_key();
-
vals->push_back(val);
if (!token->is_op(OPERATOR_LCURLY))
@@ -3345,12 +3342,22 @@ Parse::call(Expression* func)
Expression*
Parse::id_to_expression(const std::string& name, Location location,
- bool is_lhs)
+ bool is_lhs, bool is_composite_literal_key)
{
Named_object* in_function;
Named_object* named_object = this->gogo_->lookup(name, &in_function);
if (named_object == NULL)
- named_object = this->gogo_->add_unknown_name(name, location);
+ {
+ if (is_composite_literal_key)
+ {
+ // This is a composite literal key, which means that it
+ // could just be a struct field name, so avoid confusiong by
+ // not adding it to the bindings. We'll look up the name
+ // later during the lowering phase if necessary.
+ return Expression::make_composite_literal_key(name, location);
+ }
+ named_object = this->gogo_->add_unknown_name(name, location);
+ }
if (in_function != NULL
&& in_function != this->gogo_->current_function()
@@ -5167,7 +5174,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
*val = this->id_to_expression(gogo->pack_hidden_name(recv_var,
is_rv_exported),
- recv_var_loc, true);
+ recv_var_loc, true, false);
saw_comma = true;
}
else
diff --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h
index f309ee0..4a5a4b8 100644
--- a/gcc/go/gofrontend/parse.h
+++ b/gcc/go/gofrontend/parse.h
@@ -231,7 +231,7 @@ class Parse
bool* is_type_switch, bool* is_parenthesized);
Type* reassociate_chan_direction(Channel_type*, Location);
Expression* qualified_expr(Expression*, Location);
- Expression* id_to_expression(const std::string&, Location, bool);
+ Expression* id_to_expression(const std::string&, Location, bool, bool);
void statement(Label*);
bool statement_may_start_here();
void labeled_stmt(const std::string&, Location);
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 27d53df..d6cd326 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -8943,8 +8943,12 @@ Interface_type::finalize_methods()
continue;
}
+ const Typed_identifier_list* imethods = it->parse_methods_;
+ if (imethods == NULL)
+ continue;
+
Named_type* nt = t->named_type();
- if (nt != NULL && it->parse_methods_ != NULL)
+ if (nt != NULL)
{
std::vector<Named_type*>::const_iterator q;
for (q = seen.begin(); q != seen.end(); ++q)
@@ -8960,22 +8964,26 @@ Interface_type::finalize_methods()
seen.push_back(nt);
}
- const Typed_identifier_list* imethods = it->parse_methods_;
- if (imethods == NULL)
- continue;
for (Typed_identifier_list::const_iterator q = imethods->begin();
q != imethods->end();
++q)
{
if (q->name().empty())
inherit.push_back(*q);
- else if (this->find_method(q->name()) == NULL)
- this->all_methods_->push_back(Typed_identifier(q->name(),
- q->type(), tl));
else
- go_error_at(tl, "inherited method %qs is ambiguous",
- Gogo::message_name(q->name()).c_str());
+ {
+ const Typed_identifier* oldm = this->find_method(q->name());
+ if (oldm == NULL)
+ this->all_methods_->push_back(Typed_identifier(q->name(),
+ q->type(), tl));
+ else if (!Type::are_identical(q->type(), oldm->type(),
+ Type::COMPARE_TAGS, NULL))
+ go_error_at(tl, "duplicate method %qs",
+ Gogo::message_name(q->name()).c_str());
+ }
}
+
+ seen.pop_back();
}
if (!this->all_methods_->empty())